Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Pointer Problem (https://www.delphipraxis.net/41243-pointer-problem.html)

Skyrunner2 28. Feb 2005 14:36


Pointer Problem
 
Delphi-Quellcode:
 begin
           new(PFieldID);
             PFieldID:=CellQ.Pop;
             FieldID.x:=PFieldID^.x;
             FieldID.y:=PFieldID^.y;
             FieldID.Wall:=PFieldID^.Wall;
           dispose(PFieldID);
          end;
also ich hab eine warteschlang "CellQ" vom type TQueue.

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

Skyrunner2 28. Feb 2005 14:38

Re: Pointer Problem
 
hmm das porblem liegt beim speichern der objecte in der schlange in einer 2. prozedure..

Muetze1 28. Feb 2005 15:02

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:
begin
  PFieldID := CellQ.Pop;
  FieldID.x := PFieldID^.x;
  FieldID.y := PFieldID^.y;
  FieldID.Wall := PFieldID^.Wall;
  Dispose(PFieldID);
end;
/EDIT: Ganz vergessen:

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

Skyrunner2 28. Feb 2005 15:18

Re: Pointer Problem
 
sorry.. code gelöscht..

großer / keliner fehler

Muetze1 28. Feb 2005 15:33

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:
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;
(Rechtschreibfehler nicht korrigiert...)

/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

Skyrunner2 28. Feb 2005 15:44

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 12:20 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