AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Pointer Problem

Ein Thema von Skyrunner2 · begonnen am 28. Feb 2005 · letzter Beitrag vom 28. Feb 2005
Antwort Antwort
Skyrunner2

Registriert seit: 11. Jan 2005
Ort: Bochum
50 Beiträge
 
Delphi 2006 Architect
 
#1

Pointer Problem

  Alt 28. Feb 2005, 14:36
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..



.PrimGenerator ## Pointer x was:9345488
.PrimGenerator ## Pointer Y was:16
  Mit Zitat antworten Zitat
Skyrunner2

Registriert seit: 11. Jan 2005
Ort: Bochum
50 Beiträge
 
Delphi 2006 Architect
 
#2

Re: Pointer Problem

  Alt 28. Feb 2005, 14:38
hmm das porblem liegt beim speichern der objecte in der schlange in einer 2. prozedure..
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: Pointer Problem

  Alt 28. Feb 2005, 15:02
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
  Mit Zitat antworten Zitat
Skyrunner2

Registriert seit: 11. Jan 2005
Ort: Bochum
50 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Pointer Problem

  Alt 28. Feb 2005, 15:18
sorry.. code gelöscht..

großer / keliner fehler
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#5

Re: Pointer Problem

  Alt 28. Feb 2005, 15:33
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
  Mit Zitat antworten Zitat
Skyrunner2

Registriert seit: 11. Jan 2005
Ort: Bochum
50 Beiträge
 
Delphi 2006 Architect
 
#6

Re: Pointer Problem

  Alt 28. Feb 2005, 15:44
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.s.: Neighbor = US englisch; Neighbour = Britisch
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:35 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