Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ein Array in einer Klasse als private-Deklaration (https://www.delphipraxis.net/118943-ein-array-einer-klasse-als-private-deklaration.html)

RWarnecke 18. Aug 2008 12:19


Ein Array in einer Klasse als private-Deklaration
 
Hallo zusammen,

ich habe so eine Klasse erstellt :
Delphi-Quellcode:
type
  TKlasse = class(TObject)
  private
    FName : array of string;
  public
  ...
  ...
  ...
  end;
Dieses Array wird im construktor mit Daten gefüllt und ja, ich habe mir mit SetLength eine ausreichende Länge festgelegt. Nun rufe ich in einer Funktion GetMem auf und dann die Windows API-Funktion GetAdaptersAddresses, dann wird das Array FName mit irgendwelchen Hyroglyphen überschrieben. Die große Frage ist warum ?

sirius 18. Aug 2008 13:11

Re: Ein Array in einer Klasse als private-Deklaration
 
Und wie sehen die Aufrufe auf?

RWarnecke 18. Aug 2008 13:41

Re: Ein Array in einer Klasse als private-Deklaration
 
Hier wird der Array befüllt :
Delphi-Quellcode:
    SetLength(FaaiAdapters,1);
    FaaiAdapters[0] := pAdapterList;
    while FaaiAdapters[High(FaaiAdapters)].Next <> nil do begin
      SetLength(FaaiAdapters,Length(FaaiAdapters)+1);
      FaaiAdapters[High(FaaiAdapters)] := FaaiAdapters[High(FaaiAdapters)-1].Next;
    end;
Und so ist der Aufruf von GetAdaptersAddresses :
Delphi-Quellcode:
  PVOID = Pointer;

  TGetAdapterAdresses = function (Family: ULONG; Flags: cardinal; Reserved: PVOID;
    pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen: PULONG): dword; stdcall;

     error := AdaptersAddresses(AF_UNSPEC, 10, nil, nil, @buffer);
      if error <> ERROR_BUFFER_OVERFLOW then
      begin
        FreeLibrary(hdll);
        exit;
      end;
      GetMem(adapterextinfo, buffer);
      error := AdaptersAddresses(AF_UNSPEC, 10, nil, adapterextinfo, @buffer);
      if error = ERROR_SUCCESS then
Und in diesem Teil in Zeile 13 überschreibt er mir den Array FaaiAdapters.

omata 18. Aug 2008 15:27

Re: Ein Array in einer Klasse als private-Deklaration
 
Wo ist Zeile 13? genau! (Mit oder ohne Leerzeichen)

mkinzler 18. Aug 2008 15:31

Re: Ein Array in einer Klasse als private-Deklaration
 
Zudem würde ich die Größe einmal setzen und nicht bei jedem Schritt vergrößern

RWarnecke 18. Aug 2008 16:19

Re: Ein Array in einer Klasse als private-Deklaration
 
Zitat:

Zitat von omata
Wo ist Zeile 13? genau! (Mit oder ohne Leerzeichen)

Mit den Leerzeilen, ich habe die Zeilennummer genommen vom Kasten.

Zitat:

Zitat von mkinzler
Zudem würde ich die Größe einmal setzen und nicht bei jedem Schritt vergrößern

Ich kann aber die Größe nicht vorher setzen, da ich die Größe vorher ja nicht weiß.

Edit:
Erwähnt sei noch, auf meinem Windows VISTA 64Bit mit 4GB RAM funktioniert es wunderbar. Wenn ich das gleiche auf einem Windows XP SP2 oder SP3 mit 2GB RAM oder 4GB RAM ausführe, wird mir das Array durch den Aufruf von GetAdaptersAddresses überschrieben. Und auch nur dann, wenn das Array größer als Eins ist.

Edit2:
Ich habe noch ein paar Tests durchgeführt. Wenn das Array die Größe eins hat, dann funktioniert alles wunderbar. Ist das Array aber größer als eins, dann habe ich unter Windows XP SP2 und SP3 Probleme, dass mir das Array überschrieben wird. Dieses passiert aber nicht unter Windows VISTA 64Bit.

Dunkel 18. Aug 2008 19:23

Re: Ein Array in einer Klasse als private-Deklaration
 
Zitat:

Zitat von RWarnecke
Zitat:

Zitat von mkinzler
Zudem würde ich die Größe einmal setzen und nicht bei jedem Schritt vergrößern

Ich kann aber die Größe nicht vorher setzen, da ich die Größe vorher ja nicht weiß.

Gibt es denn eine maximal erreichbare Größe? Dann benutz diese und verkleiner dann das Array am Ende entsprechend der wirklich gebrauchten Größe.
Wenn es keine maximal erreichbare Größe geben sollte (oder diese bei MAXINT liegen sollte [solch ein Riesenarry anzulegen um im schlimmsten Fall nur einen Eintrag einzufügen ist definitiv sub-optimal]) dann machst Du es halt folgendermassen

Delphi-Quellcode:
const
  Delta = 500;
var
  myArray: array of string;
  myArraySize: integer;
  myItemConter: integer;
  i: integer;
begin
  myItemCounter := 0;
  myArraySize := Delta;
  SetLength(myArray, myArraySize);

  for i:= 0 to WasWeißIch do
    begin
      Inc(myItemCounter);
      myArray[i]:= "Foo"+i;
     
      if myItemCounter = myArraySize then
        begin
          Inc(myArraySize, Delta);
          SetLength(myArray, myArraySize);
        end;
    end;
 
  SetLength(myArray, myItemCounter);
Ist wesentlich schneller und ressourcenschonender als bei jedem Durchlauf das Array um 1 zu vergrößern.

omata 18. Aug 2008 20:52

Re: Ein Array in einer Klasse als private-Deklaration
 
Benutze doch TList.

grenzgaenger 18. Aug 2008 21:03

Re: Ein Array in einer Klasse als private-Deklaration
 
und wo ist der zusammenhang zu deinem eingangspost? ich kann weger die klasse noch die eigennschaft in deinen anderen post erkennen ... :glaskugel:

RWarnecke 19. Aug 2008 08:55

Re: Ein Array in einer Klasse als private-Deklaration
 
Also, ich habe jetzt wahrscheinlich den Fehler gefunden. Es lag nicht an der Art wie ich das Array erstellt habe, sondern an dem Aufruf von MSDN-Library durchsuchenGetAdaptersAddresses. Ich habe beim Aufruf das Flag von 10 auf 0 gesetzt. Jetzt wird beim Aufruf von MSDN-Library durchsuchenGetAdaptersAddresses das Array nichtmehr überschrieben. Des weiteren habe ich noch den Aufruf von GetMem in AllocMem geändert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 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