Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Stacküberlauf bei Array einer Struktur >2000 Elemente (https://www.delphipraxis.net/124853-stackueberlauf-bei-array-einer-struktur-2000-elemente.html)

DelphiManiac 26. Nov 2008 11:31


Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Hallo ich habe eine Struktur:


Delphi-Quellcode:
type
TDatensatz = record
  MesstellenNr:Byte;
  MesstellenBez:ShortString; // 16 Byte
  Tag:Byte;
  Monat:Byte;
  Jahr:Byte;
  Stunde:Byte;
  Minute:Byte;
  Status:Word;
  O2:Word;
  O2Unit:Byte;
  Temp:Word;
  Stoerung:Byte;
  ADC_V_Bat:Word;
end;
Das sind ja schoneinmal 32 Byte pro Record.

Jetzt brauche ich das 8192 mal.
Also habe ich mir eine Array angelegt:

Delphi-Quellcode:
  Datensaetze: array[0..8191] of TDatensatz;
Wenn ich nun durchiteriere und die Datensätze befülle bekomme ich einen Stack Überlauf.

Das müssten dann ungefähr 256 KByte sein, wenn ich richtig gerechnet habe. Warum bekomme ich denn einen Stacküberlauf?

Vielen Dank
Gruß
DelphiManiac

s.h.a.r.k 26. Nov 2008 11:33

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
hat wohl was mit der stack-größe zu tun, aber da kann ich dir nicht weiterhelfen.

mit einer verketteten liste und objekten solltest dieses problem nicht bekommen! (wenn ich das noch richtig weiß)

NormanNG 26. Nov 2008 11:37

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Hi,

Zitat:

MesstellenBez:ShortString; // 16 Byte
ein Shortstring belegt 2 bis 256 Bytes, je nach Länge des Strings

Uwe Raabe 26. Nov 2008 11:38

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Soweit ich weiß, ist ShortString als string[255] deklariert.
Und grundsätzlich sollte man derart große Strukturen nicht auf dem Stack anlegen. Eine Möglichkeit ist, das Array dynamisch anzulegen:

Delphi-Quellcode:
var
  DatenSaetze: array of TDatensatz;
begin
  SetLength(DatenSaetze, 8192);
  ...

DelphiManiac 26. Nov 2008 11:42

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
@NormanNG

Delphi-Quellcode:
MesstellenBez:ShortString; // 16 Byte
Ich belege nur 16 Byte des Strings, jetzt weiß ich nicht genau, wie es im Speicher abgelegt wird, bin davon ausgegangen, das nur 16 Byte belegt werden, kann mich aber täuschen.

@Uwe Raabe:

Macht es denn wirklich einen Unterschied ob ich die dynamisch oder statisch anlege?
Kann es ja mal probieren, beim dynamischen anlegen, werden die Elemente glaube ich auf den Heap geschoben, lasse mich aber gerne eines besseren belehren.

Ich probiere es mal.

DelphiManiac 26. Nov 2008 11:51

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Mit einem dynamisch angelegten Array hat man diese Probleme anscheinend wirklich nicht.

Vielleicht kann ja mal jemand kurz einen Einblick geben, warum das so ist.

Viele Grüße
und vielen Dank

DelphiManiac

Horst_ 26. Nov 2008 11:53

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Hallo,

wie iterierst Du beim befüllen, was wird dort verarbeitet.
256 Kbyte sind locker möglich. Selbst wenn der shortstring ersteinmal 256 Byte belegt.
shortstring[16] belegte auch 17 byte.
Es schätze es ist was anderes, irgendwelche Stringverarbeitungen die Speicherplatz belegen und erst sehr spät wieder freigegeben werden.

Gruß Horst

EDIT: mit dynamischem array geht es? mysteriös.

DelphiManiac 26. Nov 2008 11:58

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Also der Stacküberlauf kommt direkt beim Aufrufen der Button-Prozedur:

Delphi-Quellcode:
procedure TfrmDatalogGUI.btnLadenClick(Sender: TObject);
var
  I: Integer;
  xlsFile : TXLSFile;
  template:string;
  sprache:Integer;
  Datensaetze: array[0..8192] of TDatensatz;
  Datum:TDate;
  Uhrzeit:TTime;
  Expo:Smallint;
  O2Einheit:string;
  EndOfDataRead:Integer;
  error:integer;
begin // <------------------ Hier knallts dann sofort (nachdem die Variablen deklariert worden sind)
//  SetLength(Datensaetze,8192);
Aber mit dem dynamischen Array nicht:

Delphi-Quellcode:
procedure TfrmDatalogGUI.btnLadenClick(Sender: TObject);
var
  I: Integer;
  xlsFile : TXLSFile;
  template:string;
  sprache:Integer;
  Datensaetze: array of TDatensatz;
  Datum:TDate;
  Uhrzeit:TTime;
  Expo:Smallint;
  O2Einheit:string;
  EndOfDataRead:Integer;
  error:integer;
begin
  SetLength(Datensaetze,8192);
Ihr habt recht mit dem Shortstring belegt also wirklich 256 Byte:

Zitat:

Ein ShortString hat eine Länge von 0 bis 255 Zeichen. Obwohl sich seine Länge dynamisch ändern kann, beträgt die statische Speicherplatzzuweisung immer 256 Bytes. Im ersten Byte wird die Länge des Strings gespeichert, die restlichen 255 Byte stehen für die Zeichen zur Verfügung

mkinzler 26. Nov 2008 11:58

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
Bei dynamischen arrays wird der Inhalt auch getrennt gespeichert

DelphiManiac 26. Nov 2008 12:01

Re: Stacküberlauf bei Array einer Struktur >2000 Elemente
 
D.h. nicht zwingend hintereinander? Sondern im Speicher verteilt.

Klingt ja auch logisch, schließlich kann das Programm auch nicht wissen um wie viele Elemente das Array vergrößert wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:11 Uhr.
Seite 1 von 2  1 2      

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