AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Stack Overflow - Dynamische Arrays

Ein Thema von roboter202 · begonnen am 3. Mai 2012 · letzter Beitrag vom 4. Mai 2012
Antwort Antwort
roboter202

Registriert seit: 6. Mär 2011
98 Beiträge
 
Delphi 6 Professional
 
#1

Stack Overflow - Dynamische Arrays

  Alt 3. Mai 2012, 21:36
Hi,


Ich generiere ein Labyrinth mit einer rekursiven Prozedur.



ich hab den Code:

Delphi-Quellcode:
procedure TWorld.generate(_x, _y: Integer);
var
  neighbours: array of TVect2i;
  r: ShortInt;
begin
  //list of unvisited neighbours
  if (_y <> 0) then
  begin
    if (cellMap[_x, _y -1] = false) then //TOP
    begin
      SetLength(neighbours, Length(neighbours) +1);
      neighbours[high(neighbours)].x := _x;
      neighbours[high(neighbours)].x := _y -1;
    end;
  end;

  if (_x <> 0) then
  begin
    if (cellMap[_x -1, _y] = false) then //LEFT
    begin
      SetLength(neighbours, Length(neighbours) +1);
      neighbours[high(neighbours)].x := _x -1;
      neighbours[high(neighbours)].x := _y ;
    end;
  end;

  if (_y <> height -1) then
  begin
    if (cellMap[_x, _y +1] = false) then //Bottom
    begin
      SetLength(neighbours, Length(neighbours) +1);
      neighbours[high(neighbours)].x := _x ;
      neighbours[high(neighbours)].x := _y +1;
    end;
  end;

  if (_x <> width -1) then
  begin
    if (cellMap[_x +1, _y] = false) then //RIGHT
    begin
      SetLength(neighbours, Length(neighbours) +1);
      neighbours[high(neighbours)].x := _x +1;
      neighbours[high(neighbours)].x := _y ;
    end;
  end;
  //

  if not cellMap[_x, _y] then //Was this cell vistited?
  begin
    //Mark as visited
    cellMap[_x, _y] := true;
    if Length(neighbours) > 1 then //Can I go on with other paths here?
    begin
      //Move to Stack
      setLength(cellStack, Length(cellStack) +1);
      cellStack[high(cellStack)].x := _x;
      cellStack[high(cellStack)].x := _y;
    end;
  end;


  if Length(neighbours) > 0 then
  begin
    //Pick a random neighbour
    r := Random(Length(neighbours));
    //Remove Wall
    if neighbours[r].x > _x then
    begin
      //Right
      wallMap[_x, _y, 1] := true;
    end else
    if neighbours[r].x < _x then
    begin
      //Left
      wallMap[_x -1, _y, 1] := true;
    end else
    if neighbours[r].y > _y then
    begin
      //Bottom
      wallMap[_x, _y, 0] := true;
    end else
    if neighbours[r].y < _y then
    begin
      //Top
      wallMap[_x, _y -1, 0] := true;
    end;
    generate(neighbours[r].x, neighbours[r].y);

  end else
  begin
    if stackPos < high(cellStack) then
    begin
      stackPos := stackPos +1;
      generate(cellStack[stackPos].x, cellStack[stackPos].y)
    end;
  end;
end;
und was auch noch wichtig sein könnte ist


Delphi-Quellcode:
     
cellMap: array of array of Boolean;
wallMap: array of array of array [0..1] of Boolean; //0 => Horizontal; 1 => Vertical; X,Y of Cell to Left Top
cellStack: array of TVect2i;
und

Delphi-Quellcode:
  
TVect2i = record
    x,y: Integer;
  end;
Jetzt bekomme ich wenn ich width und height auf 100 setze einen Stack Overflow. Warum ich hab gelesen das es bei einem rekursiven Prozeduraufruf passieren kann. (Hab ich ja) aber was kann ich denn jetzt tun. Muss ich das Zeug was die Prozedur braucht auf einen dynamischen Array schmeißen oder geht das auch anders?

Gruß roboter202
Christian
i := 0 ; While i = 0 do beep ;
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
870 Beiträge
 
#2

AW: Stack Overflow - Dynamische Arrays

  Alt 3. Mai 2012, 22:00
Stack overflow kommt daher, daß die Rekursion nicht abbricht, sondern sich irgendwo in einer Endlosschleife verfängt. Dieser Endlosigkeit setzt die Endlichkeit des Stack(speicher)s jedoch irgendwann ein Ende.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
27.569 Beiträge
 
Delphi XE3 Professional
 
#3

AW: Stack Overflow - Dynamische Arrays

  Alt 3. Mai 2012, 22:53
Es währe auch zu einfach, wenn alle Programmierer wüßten was ein Debugger ist und wie man den verwendet.
Und ja, selbst Delphi 7 kennt einen Stack-Trace (Aufruf-Stack).
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Popov

Registriert seit: 15. Mai 2005
Ort: Köln
2.131 Beiträge
 
Delphi 7 Professional
 
#4

AW: Stack Overflow - Dynamische Arrays

  Alt 4. Mai 2012, 00:34
Ich hab auch irgendwann ein Labyrinth geprogt und es auch rekursiv berechnet. Ob ich es 20x20 oder 500x500 mache, es funktioniert ohne Fehlermeldung. Die Größe dürfte also nicht das Problem sein. Ich tippe drauf, dass es irgendwo eine lost in space Geschichte wird.
Popov
Abrakadabra, Embarcadero, dreimal schwarzer Kater...
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#5

AW: Stack Overflow - Dynamische Arrays

  Alt 4. Mai 2012, 06:02
Rekursiv <> Rekursiv.
Hier wird für jeden Nachbarn die Routine rekursiv aufgerufen, was bei einem 100x100 Feld entsprechend viele Aufrufe bedeuten könnte.

Da es sich um eine Rechtsrekursion handelt, kann diese bedenkenlos in eine Iteration umgewandelt werden, ohne Gehirnwindungskrämpfe zu bekommen.
  Mit Zitat antworten Zitat
roboter202

Registriert seit: 6. Mär 2011
98 Beiträge
 
Delphi 6 Professional
 
#6

AW: Stack Overflow - Dynamische Arrays

  Alt 4. Mai 2012, 13:05
Stack overflow kommt daher, daß die Rekursion nicht abbricht, sondern sich irgendwo in einer Endlosschleife verfängt. Dieser Endlosigkeit setzt die Endlichkeit des Stack(speicher)s jedoch irgendwann ein Ende.
Nein das stimmt nicht irgendwann gibt es keine Zellen ohne Nachbarn mehr

Code:
Rekursiv <> Rekursiv.
Hier wird für jeden Nachbarn die Routine rekursiv aufgerufen, was bei einem 100x100 Feld entsprechend viele Aufrufe bedeuten könnte.

Da es sich um eine Rechtsrekursion handelt, kann diese bedenkenlos in eine Iteration umgewandelt werden, ohne Gehirnwindungskrämpfe zu bekommen.
Stimmt wenn ich einen while-Schleife nehme und den Code etwas modifiziere dann müsst das auch gehen. Da bin heute morgen auch drauf gekommen.

DANKE!!!
Christian
i := 0 ; While i = 0 do beep ;
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2014 by Daniel R. Wolf