![]() |
Problem mit Pointern
Delphi-Quellcode:
PKnoten = ^TKnoten;
TKnoten = record // Record für Knoten public pSuper ,pBit0, pBit1: PKnoten; bSuper: boolean; iHaeufigkeit: int64; cBuchstabe: char; end; ... var aKnoten: array of TKnoten;
Delphi-Quellcode:
Bei der ersten Message kommt 3 raus (was richtig ist), beim zweiten mal jedoch 0.
ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit));
ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit)); Die Beiden Zeilen stehen genau hintereinander. Nur wo ist da der Fehler das das passiert? (Delphi2005) |
Re: Problem mit Pointern
Meine Glaskugel sagt mir, dass du die Zeiger nicht mit New initialisiert hast.
New(aKnoten[4].pBit0); |
Re: Problem mit Pointern
Mein Verstand sagt mir, dass Dezipaitor .iHaeufigkeit noch entfernen wollte. Mein Verstand war langsamer als seine Finger...
Meine Glaskugel sagt mir, dass du dir u.a. Pointer auf Array Elemente von aKnoten vermerkt, u.a. in anderen Knoten der Liste. Leider aber auch zwischendurch die Liste verlängerst/verkürzt. Dabei wiederrum werden aber u.U. alle Zeiger ungültig in der Liste, da ein dynamisches Array frei im Speicher bewegt wird bei der Realloziierung, abhängig davon wo Speicher zur Verfügung steht. |
Re: Problem mit Pointern
bei 2 mal der exakt gleichen Anweisung hintereinander passieren verschiedene Dinge? Wenn dem so ist so genügt der zusammgengekürzte Quelltext den du uns offenbart hast nicht aus um den Fehler zu finden.
|
Re: Problem mit Pointern
Hi,
ich würde es vermeiden, eine Verkettete Listen Struktur in dynamischen Arrays abzulegen. Das widerspricht sich für mich irgendwie. Hier wird mit New() und Dispose() gearbeitet. Wenn Du in dynamischen Arrays arbeiten willst, verwende keine Zeiger, sondern Indices um auf andere Elemente in dem Array zu verweisen. Das gehört wieder zusammen. Gruss |
Re: Problem mit Pointern
Delphi-Quellcode:
var
Form1: TForm1; aKnoten: array of TKnoten; const cBuchs: array[0..3] of char = ('c', 'a', 'b', 'd'); iBuchs: array[0..3] of int64 = (6, 5, 2, 3); implementation {$R *.dfm} {$O-} procedure TForm1.Button1Click(Sender: TObject); var i, x: int64; // x = Length aKnoten Mi0, Mi1: TMinInd; Point: PKnoten; bitcode: string; begin // anderweitige Initialisierung x := length(iBuchs); SetLength(aKnoten, x); // anderweitige Initialisierung -> Complete // Komplettinitialisierung des verwendeten Arrays i := 0; repeat aKnoten[i].cBuchstabe := cbuchs[i]; aKnoten[i].iHaeufigkeit := ibuchs[i]; aKnoten[i].pSuper := nil; aKnoten[i].pBit0 := nil; aKnoten[i].pBit1 := nil; inc(i); until (i = x); // Komplettinitialisierung des verwendeten Arrays -> Complete // Damit Schleife nicht gleich abbricht // Danach Baumerstellung mi1.haeuf := high(int64) - 1; while mi1.haeuf <> high(int64) do begin mi1.index := -1; mi1.haeuf := high(int64); mi0.index := -1; mi0.haeuf := high(int64); i := -1; repeat inc(i); if (aKnoten[i].iHaeufigkeit < mi1.haeuf) and (aKnoten[i].pSuper = nil) then begin mi1.index := mi0.index; mi1.haeuf := mi0.haeuf; mi0.index := i; mi0.haeuf := aKnoten[i].iHaeufigkeit; end; until (i = x - 1); Memo1.Lines.Add('indexi: ' + IntToStr(i)); Memo1.Lines.Add('index0: ' + IntToStr(mi0.index)); Memo1.Lines.Add('haeuf0: ' + IntToStr(mi0.haeuf)); Memo1.Lines.Add('index1: ' + IntToStr(mi1.index)); Memo1.Lines.Add('haeuf1: ' + IntToStr(mi1.haeuf)); Memo1.Lines.Add('------------'); // neuen Knoten hinzufügen if mi1.index <> -1 then begin inc(x); SetLength(aKnoten, x); aKnoten[x - 1].pSuper := nil; aKnoten[x - 1].iHaeufigkeit := mi1.haeuf + mi0.haeuf; aKnoten[x - 1].pBit0 := @aKnoten[mi0.index]; aKnoten[x - 1].pBit1 := @aKnoten[mi1.index]; aKnoten[x - 1].cBuchstabe := #0; aKnoten[mi0.index].pSuper := @aKnoten[x - 1]; aKnoten[mi0.index].bSuper := false; aKnoten[mi1.index].pSuper := @aKnoten[x - 1]; aKnoten[mi1.index].bSuper := true; end; // neuen Knoten hinzufügen -> Complete end; // BitCode auslesen! i := 0; { repeat if (aKnoten[i].pBit0 = nil) and (aKnoten[i].pBit1 = nil) then begin // Hier Code zum BitCode auslesen schreiben! bitcode := ''; if aKnoten[i].bSuper then bitcode := '1' + bitcode else bitcode := '0' + bitcode; Point := aKnoten[i].pSuper; while (Point^.pSuper <> nil) do begin Point := Point^.pSuper; if Point.bSuper then bitcode := '1' + bitcode else bitcode := '0' + bitcode; end; Memo1.Lines.Add('BitCode für *' + aKnoten[i].cBuchstabe + '* =' + bitcode); end; inc(i); until i = length(aKnoten); } Point := aKnoten[4].pBit0; ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit)); ShowMessage(IntToStr(aKnoten[4].pBit0^.iHaeufigkeit)); { point := aKnoten[3].pSuper; while (point^.pSuper <> nil) do begin ShowMessage(IntToStr(point^.iHaeufigkeit)); point := point^.pSuper; end; } // BitCode auslesen! -> Complete end; end. |
Re: Problem mit Pointern
Muetze1 hat den Fehler richtig vermutet gehabt:
Du holst dir die Adresse eines Arrayelementes und speicherst/merkst dir diese
Delphi-Quellcode:
Wenn du dann allerdings mit
aKnoten[mi0.index].pSuper := @aKnoten[x - 1];
Delphi-Quellcode:
die Größe des Arrays änderst wird unter umständen das Array wo anders in den Speicher hinkopiert (weil an der aktuellen Position nicht genug Platz ist zum vergrößern).
SetLength(aKnoten, x);
Somit hast du in .pSuper eine alte Adresse stehen die nicht mehr aktuell ist weil das Array jetzt wo ganz anders im Speicher liegt. |
Re: Problem mit Pointern
naja nur beim ersten aufruf kommt das richtige ergebnis.. in der zeile danach nicht..
und unter Delphi 2008 läuft es ohne fehler. Unter Delphi2005 bekomme ich den Fehler... |
Re: Problem mit Pointern
Zitat:
Nach jeder Vergrößerung können alle Pointer auf Elemente dieses Arrays ungültig werden. Das ist im Prinzip in jeder Delphiversion so. Verwende statt dessen ein TList-Object und erstelle die Knoten mit New und gib diese mit Dispose wieder frei. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz