AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Größe bei dyn. Arrays automatisch?

Ein Thema von jensen82 · begonnen am 27. Mai 2013 · letzter Beitrag vom 29. Mai 2013
Antwort Antwort
Seite 1 von 2  1 2      
jensen82

Registriert seit: 4. Mai 2013
4 Beiträge
 
#1

Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 15:52
Delphi-Version: 2010
Hallo!

Ich habe schon einige Jahre Programmiererfahrung in anderen Sprachen und bin vor kurzem zu Delphi "gewechselt". Klar...entweder man kann programmieren oder eben nicht.
Mir ist allerdings etwas aufgefallen:

Ich lese Hardware-Infos via WQL und WMI aus und bekomme via OLE und Wbem-Script Daten zurück (Variant). Damit wird ein Record gefüllt.
Hier werden u.a "array UINT16" zurückgegeben. Im Record habe ich daher data : array of Integer; stehen. Das Tolle ist...es geht, ohne SetLength() zu verwenden.

Meine Frage ist: Warum macht Delphi das autom. und warum wird immer empfohlen via SetLength die Größe anzugeben?

Ist die Variante sicher? Also ohne SetLength ?

Hier mal ein Code-Ausschnitt:

Delphi-Quellcode:
TDiskInfo = record
    Availability: Integer; // Uint16
    BytesPerSector: Integer; // Uint32
    Capabilities: array of Integer; // Array of Uint16

// Hier jetzt die Zuweisung:
if not VarIsNull(FWbemObject.Capabilities) then
        begin
          disk.Capabilities := FWbemObject.Capabilities;
end

// klappt ohne Probleme
Ich würde mich über Konstruktives freuen

Und bitte nicht lachen...der Wechsel zu Delphi ist noch nciht ganz abgeschlossen.

Danke sehr!
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:03
Hallo,
meines Wissen übergibst Du hier
disk.Capabilities := FWbemObject.Capabilities; die Adresse von einem anderen Array und nicht den Inhalt des anderen Arrays.

Grüße
Klaus
Klaus

Geändert von Klaus01 (27. Mai 2013 um 16:27 Uhr) Grund: Wissen nicht ausreichend ;o)
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:03
Das ist absolut gefährlich! Ein dynamisches Array ist zunächst nur ein Pointer an eine Adresse. Wenn Delphi nicht gesagt bekommt, wie viele Bytes dahinter für das Array zu reservieren sind, kann/wird dir der Delphi Speichermanager diesen Bereich mit allen möglichen anderen Dingen aus deinem Programm beschreiben - oder schlimmer noch: Es hat dies schon getan, jetzt kommt aber die API Funktion daher - die nichts davon weiss, dass der Speicher schon anders benutzt wird - und jodelt dort fröhlich seine Ausgaben hin.
Das geht genau so lange gut, wie dein Programm zufällig nichts weiteres mit dem Speicher ab der Array-Position macht. Und NUR dann. Damit lassen sich die wildesten Fehler herstellen, an Stellen die man erst nach Tagen/Wochen des Suchens mit dem Array in Zusammenhang bringen könnte.

IMMER die Größe vor der Benutzung setzen!!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#4

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:10
Das ist absolut gefährlich!
Ist es nicht!

Bei der Zuweisung einer Varianten an eine Variable eines definierten Typs versucht der Compiler eine implizite Umwandlung. Im Fall eines dynamischen Arrays wird _VarToDynArray aufgerufen, das mittels DynArrayFromVariant eine Umwandlung vornimmt. Sollte das nicht funktionieren wird eine EVariantTypeCastError-Exception ausgelöst.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.176 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:14
Ignoriert mich

Geändert von Der schöne Günther (27. Mai 2013 um 16:16 Uhr) Grund: Gehirn eingeschlafen
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#6

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:22
Gürks, OLE-Geschlumpfe. Okay, da habe ich etwas zu oberflächlich gelesen. Was aber von meiner Aussage oben bleibt ist, dass sie zutrifft, wenn man ohne "magische" Resourcen hantiert.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von baumina
baumina

Registriert seit: 5. Mai 2008
Ort: Oberschwaben
1.275 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:28
Gürks, OLE-Geschlumpfe. Okay, da habe ich etwas zu oberflächlich gelesen. Was aber von meiner Aussage oben bleibt ist, dass sie zutrifft, wenn man ohne "magische" Resourcen hantiert.
Ein Variant ist magisch?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#8

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 16:34
Gürks, OLE-Geschlumpfe. Okay, da habe ich etwas zu oberflächlich gelesen. Was aber von meiner Aussage oben bleibt ist, dass sie zutrifft, wenn man ohne "magische" Resourcen hantiert.
Das hat gar nichts mit OLE zu tun, sondern damit wie Delphi mit Variants umgeht. Der folgende Code ist also durchaus korrekt und ungefährlich:

Delphi-Quellcode:
var
  A: array of Integer;
  V: Variant;
  I: Integer;
begin
  V := VarArrayCreate([0,9], varInteger);
  for I := 0 to 9 do
    V[I] := I;
  A := V;
  for I := 0 to 9 do
    Assert(V[I] = I);

  VarClear(V);
  V := A;
  for I := 0 to 9 do
    Assert(V[I] = I);

end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#9

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 17:19
Aus pascalscher Sicht sind Variants durchaus "magisch", da mit vergleichsweise viel Compiler Magic ausgestattet, und (u.a.) die Typstrenge aufweichend. Und gerade variante Arrays (für die es ohne OLE imho anfangs wenig Bedarf in Delphi gegeben hätte) bringen einfach viele Automatismen mit, die die dynamischen Arrays, über die man sich normalerweise in Delphi unterhält, einfach nicht haben. Ich hoffe man versteht mich jetzt richtiger.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
jensen82

Registriert seit: 4. Mai 2013
4 Beiträge
 
#10

AW: Größe bei dyn. Arrays automatisch?

  Alt 27. Mai 2013, 19:10
Hey!

Also ist das in Ordnung... ? Aber warum in aller Welt muss ich die Länge des Arrays nicht angeben?
Wäre es generisch, z.B. List oder vector aus C++ wäre ja mit .Add(meinVar) alles fein. Kann mir das jemand erklären?

Hier nochmal ein wenig Code:

Delphi-Quellcode:
function GetAllDisks(sHostName: String; sUserName: String;
  sPassword: String): TDiskInfoList;
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator: OLEVariant;
  FWMIService: OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject: OLEVariant;
  oEnum: IEnumvariant;
  iValue: LongWord;
  disk: TDiskInfo;
  diskList: TDiskInfoList;
begin
  try
    CoInitialize(nil);
    try
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService := FSWbemLocator.ConnectServer(sHostName, 'root\CIMV2',
        sUserName, sPassword);
      FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_DiskDrive',
        'WQL', wbemFlagForwardOnly);
      oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
      begin
        //if not VarIsNull(FWbemObject.Availability) then
          disk.Availability := FWbemObject.Availability;

        if not VarIsNull(FWbemObject.BytesPerSector) then
          disk.BytesPerSector := FWbemObject.BytesPerSector;

        if not VarIsNull(FWbemObject.Capabilities) then
          disk.Capabilities := FWbemObject.Capabilities;
Letztendlich gibt die Funktion eine List zurück.

Ich danke euch vielmals.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz