![]() |
Pointer Problem
Delphi-Quellcode:
also ich hab eine warteschlang "CellQ" vom type TQueue.
begin
new(PFieldID); PFieldID:=CellQ.Pop; FieldID.x:=PFieldID^.x; FieldID.y:=PFieldID^.y; FieldID.Wall:=PFieldID^.Wall; dispose(PFieldID); end; Die elemente in dieser schlange sind (pointer auf) einen record, mit (u.A.) x,y:Integer. die elemente werden in einer externen prozedure der schlange hinzugefügt (die schlange wird via call by reference and diese prozedure übergeben). Nach dem hinzufügen sind die werte auch richting (ich check intern noch ein mal), aber soblad ich den oben stehenden quelltext durchlaufen lasse wird folgender wert in PFieldID geschireben.. :o .PrimGenerator ## Pointer x was:9345488 .PrimGenerator ## Pointer Y was:16 |
Re: Pointer Problem
hmm das porblem liegt beim speichern der objecte in der schlange in einer 2. prozedure..
|
Re: Pointer Problem
Moin!
Pop gibt dir den Zeiger zurück den du beim hinzufügen angegeben hast - somit ist das anlegen mit new() speicherverschwendung --- du überschreibst den Zeiger auf diesen neuen Speicher ja durch das Pop und verlierst somit den Bezug auf diesen neuen Speicher und kannst ihn nie wieder freigeben - also ein typisches Speicherleck.
Delphi-Quellcode:
/EDIT: Ganz vergessen:
begin
PFieldID := CellQ.Pop; FieldID.x := PFieldID^.x; FieldID.y := PFieldID^.y; FieldID.Wall := PFieldID^.Wall; Dispose(PFieldID); end; Ja, es sollte ein Problem beim hinzufügen der Elemente sein. Das rausholen wie du es hier machst bzw. wie es mein korrigierter Quellcode macht (der nur kein Speicherleck hat, aber das gleiche macht) sollten kein Fehler produzieren - ausser die Daten in der Queue sind fehlerhaft. Daher: poste mal den Quellcode wo du den Queue befüllst. MfG Muetze1 |
Re: Pointer Problem
sorry.. code gelöscht..
großer / keliner fehler |
Re: Pointer Problem
Moin!
Ok, ein paar Dinge die mir aufgefallen sind: 1. Neighbour - mit u - nur als kleiner Hinweis... *g* 2. Du machst zum Anfang ein New, was den Speicher für CellWallID holt und den Zeiger darauf zeigen lässt. Ok, aber nun ist das Problem, das du diesen einen Wert mehrfach einfügen könntest. Wenn x > 0 und x > width ist, dann benutzt du TempWallID doppelt und fügst ihn auch 2x hinzu. Wenn du nun einen dieser beiden einträge rausholst und freigibst, dann ist der zweite auch gleichzeitig mit ungültig - weil du hast 2x jeweils einen zeiger auf einen speicherbereich der dann beim ersten mal rausholen freigegeben ist - aber der zweite zeiger zeigt ja immernoch drauf... 3. noch zu 2.: wenn du TempWallID Werte hinzufügst und dann TempWallID der Queue hinzufügst, dann fügst du nur einen Zeiger auf die Daten in die Queue - wenn du also danach TempWallID nochmals andere Werte änderst, dann änderst du die Werte des in der Queue befindlichen Elementes - weil beides sind Zeiger die auf einen und den gleichen Speicherplatz zeigen! 4. Du fügst einen Zeiger auf den Speicherbereich (sprich auf CellWallID) hinzu und gibst danach am Ende mit Dispose den Speicher frei. Dies ist aber schlecht, da Dispose() den mit New() angelegten Speicher für CellWallID freigibt und danach zeigt TempWallID und auch der Eintrag in der Queue auf einen Speicherbereich der freigegeben wurde - somit kracht es selbstverständlich beim Zugriff. Mach es so:
Delphi-Quellcode:
(Rechtschreibfehler nicht korrigiert...)
Procedure Tmaze.NiceNeighbors(X,Y:Integer;Likes:Pointer;var CellQ:TQueue);
Var TempWallID : ^CellWallID; i : integer; begin LogForm.APPEND('########Tmaze.NiceNeighbors########'); LogForm.APPEND('.NiceNeighbors ## Hello!'); If x>0 then begin LogForm.APPEND('.NiceNeighbors ## x>0'); If MazeMemImg[x-1,y].Data=Likes then begin New(TempWallID); TempWallID^.x := x-1; TempWallID^.y := y; TempWallID^.Wall := East; CellQ.Push(TempWallID); LogForm.APPEND('.NiceNeighbors ## I like '+inttostr(x-1)+','+inttostr(y)); LogForm.APPEND('.NiceNeighbors ## Adding to Q:'); LogForm.APPEND('.NiceNeighbors ## X:'+inttostr(TempWallID^.x)); LogForm.APPEND('.NiceNeighbors ## Y:'+inttostr(TempWallID^.y)); LogForm.APPEND('.NiceNeighbors ## Wall: East'); LogForm.APPEND('.NiceNeighbors ## CellQ.peek... '); end; end; If x<width then begin LogForm.APPEND('.NiceNeighbors ## x<width'); If MazeMemImg[x+1,y].Data=Likes then begin New(TempWallID); TempWallID^.x:=x; TempWallID^.y:=y; TempWallID^.Wall:=East; CellQ.Push(TempWallID); LogForm.APPEND('.NiceNeighbors ## TempWallID^.x:=x;'); LogForm.APPEND('.NiceNeighbors ## TempWallID^.y:=y;'); LogForm.APPEND('.NiceNeighbors ## TempWallID^.Wall:=East;'); LogForm.APPEND('.NiceNeighbors ## CellQ.Push(TempWallID);'); LogForm.APPEND('.NiceNeighbors ## I like '+inttostr(x+1)+','+inttostr(y)); LogForm.APPEND('.NiceNeighbors ## Adding to Q:'); LogForm.APPEND('.NiceNeighbors ## X:'+inttostr(x)); LogForm.APPEND('.NiceNeighbors ## Y:'+inttostr(y)); LogForm.APPEND('.NiceNeighbors ## Wall: East'); LogForm.APPEND('.NiceNeighbors ######'); end; end; If y>0 then begin LogForm.APPEND('.NiceNeighbors ## y>0'); If MazeMemImg[x,y-1].Data=Likes then begin New(TempWallID); TempWallID^.x := x; TempWallID^.y := y-1; TempWallID^.Wall := South; CellQ.Push(TempWallID); LogForm.APPEND('.NiceNeighbors ## I like '+inttostr(x)+','+inttostr(y-1)); LogForm.APPEND('.NiceNeighbors ## Adding to Q:'); LogForm.APPEND('.NiceNeighbors ## X:'+inttostr(x)); LogForm.APPEND('.NiceNeighbors ## Y:'+inttostr(y-1)); LogForm.APPEND('.NiceNeighbors ## Wall: South'); LogForm.APPEND('.NiceNeighbors ######'); end; end; If y<height then begin LogForm.APPEND('.NiceNeighbors ## y<height'); If MazeMemImg[x,y+1].Data=Likes then begin New(TempWallID); TempWallID^.x := x; TempWallID^.y := y; TempWallID^.Wall := South; CellQ.Push(TempWallID); LogForm.APPEND('.NiceNeighbors ## I like '+inttostr(x)+','+inttostr(y+1)); LogForm.APPEND('.NiceNeighbors ## Adding to Q:'); LogForm.APPEND('.NiceNeighbors ## X:'+inttostr(x)); LogForm.APPEND('.NiceNeighbors ## Y:'+inttostr(y)); LogForm.APPEND('.NiceNeighbors ## Wall: South'); LogForm.APPEND('.NiceNeighbors ######'); end; end; end; /EDIT: Das mit Peek hat nix zu sagen - der gibt dir den gleichen Zeiger zurück als wie den, den du hinzufügst... Das Dispose() am Schluss ist das fehlerhafte - du kannst alle Peek's wieder rausschmeissen und das Dispose(), danach sollte es klappen (bzw. wie ich es nun schon gemacht habe). Das mit dem New() in den Einzelbedingungen hast du ja nun schon nachträglich geändert. MfG Muetze1 |
Re: Pointer Problem
ah ja.. das macht sinn!!!
Super!!! hmm so vergoldet man ~2 stunden.. lol ja in TP in der Schule sag unser lehrer immer Dispose brauchen wir nicht.. :P p.s.: Neighbor = US englisch; Neighbour = Britisch ;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:24 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 by Thomas Breitkreuz