Autor Beitrag
mariok
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mo 26.04.04 18:00 
Hallo liebe Delphi-Programmierer,

ich programmiere in Delphi 5 und habe folgendes Problem. In einen Array von Pointern (Artikelliste) sollen die Adressen von mehreren Records gespeichert
werden. Die Prozedur, welche die Daten in das Record einließt und dann die Adresse an den Array übergibt, wird mehrmals abhängig von der Zahl der Artikel durchgeführt.
Das Problem besteht darin, das ca. beim 10 oder 11. Aufruf dieser Prozedur an einer bestimmten Stelle innerhalb dieser die folgende Fehlermeldung kommt: "Im Projekt ... ist eine Exception der Klasse EInvalidPointer aufgetreten. Meldung: Ungültige Zeigeroperation..."

Ich habe unten den Quellcode angegeben. Falls mir jemand weiterhelfen könnte, würde ich mich sehr freuen.


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
type POptions = ^AOptions;
     
     AOptions = record
       Pos: string;
       Beschr: String;
       opt_nummer: array of single;   //In diesen Arrays befinden sich jeweils so ca. 10-15 Elemente des jeweiligen Typs
       opt_anzahl: array of integer;
       opt_menge: array of single;
       opt_text: tstringlist;
       opt_einheit: tstringlist;
     end;

...

artikelliste: array of POptions;      //global definiert

...

setlength(artikelliste, 40);        //Anweisung wird einer Prozedur FormCreate ausgeführt (und NUR hier)

...


XXRec: POptions;          //lokal in einer weiteren Prozedur deklariert
New(XXRec);

...              //Werte in XXRec einlesen (obiges Record wird mit Daten gefüllt)

for i:=0 to length(artikelliste)-1 do
  if (artikelliste<span style="font-style: italic"> = nilthen
  begin
      artikelliste[i] := XXrec;
      break;  <---------------------An diesem Punkt (mit Ausführen der break-Anweisung) 
  end;                    kommt es im 10 o. 11. Durchlauf zur Fehlermeldung. Der 
end;              Zeiger XXRec beeinhaltet zu diesem Zeitpunkt eine Speicheradresse, 
              die der Artikelliste auch zugewiesen wurde.



Ich habe auch schon versucht, die Größe des Arrays Artikelliste dynamisch mit [i]setlength zuzuweisen. Der Array wurde hierbei vor der Zuweisung eines
neuen Elements um ein Element erweitert. Auch dies führte ca. im 10. Durchlauf zu einer Fehlermeldung.

Bis jetzt habe ich die Vermutung, das dies ein Speicherplatzproblem sein könnte. Deswegen würde ich gerne nach jeder Datenzuweisung an den Zeiger XXRec die wirkliche Größe dieses Records ermitteln um nach dem 10. Durchlauf feststellen zu können, wieviel Speicherplatz bis dahin verbraucht wurde.
Mein Problem hierbei: Wie ermittelt man zuverlässig, wieviel Speicherplatz ein String und eine TStringList insgesamt im Speicher belegen?
Die Funktion sizeof bringt hier stets 4 Byte und ich vermute, dies ist nur der Speicherplatz, den der Zeiger auf den String verbraucht.
Ich kann zwar noch eine Funktion sizeofmem verwenden, aber mit dieser erhielt ich bis jetzt auch keine ergebnisse, da ich ihr keine strings übergeben kann
bzw. wenn ich ihr pointer übergab, kam 0 als Ergebniss heraus.

Deshalb meine zweite Frage: gibt es eine Funktion, mit der man ermiiteln kann, wieviel Speicherplatz ein String belegt (am besten noch incl. des Zeigers auf den String)?

Es wurde auch schon versucht, die Records mit dem Datentyp TList zu verwalten. Bei diesem kam ähnlich wie bei meinem Array so ca. bei der 10. oder 11.
tlist.add-Anweisung die Fehlermeldung, dass eine üngültige Zeigeroperation stattgefunden hat.


Ich würde mich sehr freuen, wenn mir jemand helfen könnte
Liebe Grüße
mario

Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt.
Loryn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 34

Win 98, ME
D4 Stand.
BeitragVerfasst: Di 27.04.04 22:13 
Hallo Mario,

bei deinem Fehler glaube ich nicht an ein Speicherplatzproblem. Artikelliste hat Platz für 40 Einträge und in der for-Schleife stellst du sicher, dass nur auf gültige Array-Elemente zugegriffen wird.

Die Exception EInvalidPointer weist darauf hin, dass der Pointer (XXRec) ungültig ist, der Artikelliste zugewiesen werden soll. Wie kann XXRec ein ungültiger Pointer sein? Das wäre z.B. dann der Fall, wenn XXRec mittels der Prozedur Dispose frei gegeben wurde (irgendwann zwischen New(XXRec) und artikelliste[i] := XXRec).

Zu deiner zweiten Frage Speicherplatzbedarf eines Strings:
var MyString: String;
Length(MyString) gibt die Anzahl Zeichen (Bytes) an, die in MyString stehen.
SizeOf(MyString) liefert 4, da MyString eigentlich ein Pointer ist.

Gruß Loryn