2016-08-18 3 views
-1

Ich versuche, die folgende Funktion zu implementieren. was es tut ist:Ich bin nicht in der Lage zu verstehen, warum dieser Block Code Segmentation Fehler

  1. nimmt eine Koordinate.
  2. weist den umgebenden Zellen Gewichte zu.
  3. speichert diese Gewichte und Zellrichtung in einer Karte.
  4. loops durch die Karte. beginnend mit dem niedrigsten Gewicht.
  5. Aufrufe werden erneut mit der Nachbarzellenkoordinate verschoben.

-Code-Schnipsel:

120 void move(const int x, const int y) 
121 { 
122   map<int, int> nextDir; 
123   map<int, int>::iterator it; 
124   if((x == maxX - 1) && (y == maxY - 1)) 
125   { 
126     int groundCopy[maxX][maxY]; 
127     memcpy(((void *)&groundCopy), ((void *)&ground), sizeof(groundCopy)); 
128     traceBack(x, y); 
129     memcpy(((void *)&ground), ((void *)&groundCopy), sizeof(ground)); 
130     printPPM(); 
131   } 
132   for(int i = 0; i < 8; ++i) 
133   { 
134     if(!isValid(x + dirX[i], y + dirY[i])) 
135       continue; 
136     int temp = weight[x][y][0] + ground[x + dirX[i]][y + dirY[i]] + disWeight(x, y, x + dirX[i], y + dirY[i]); 
137     if(!(weight[x + dirX[i]][y + dirY[i]][0] == numeric_limits<int>::max())) 
138       temp += weight[x + dirX[i]][y + dirY[i]][0]; 
139     if(temp < weight[x + dirX[i]][y + dirY[i]][0]) 
140     { 
141       weight[x + dirX[i]][y + dirY[i]][0] = temp; 
142       weight[x + dirX[i]][y + dirY[i]][1] = 7 - i; 
143       nextDir[temp] = i; 
144     } 
145     else 
146       continue; 
147   } 
148   for(it = nextDir.begin(); it != nextDir.end(); ++it) 
149     move(x + dirX[it->second], y + dirY[it->second]); 
150 } 

Backtrace Info:

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000401760 in move (x=<error reading variable: Cannot access memory at address 0x7fffff5ab18c>, y=<error reading variable: Cannot access memory at address 0x7fffff5ab188>) at codes/terrainExample.cpp:121 
121 { 
(gdb) bt 
#0 0x0000000000401760 in move (x=<error reading variable: Cannot access memory at address 0x7fffff5ab18c>, y=<error reading variable: Cannot access memory at address 0x7fffff5ab188>) at codes/terrainExample.cpp:121 
#1 0x0000000000401bfa in move (x=0, y=1) at codes/terrainExample.cpp:149 
#2 0x0000000000401bfa in move (x=0, y=0) at codes/terrainExample.cpp:149 
#3 0x0000000000401dbb in solve() at codes/terrainExample.cpp:167 
#4 0x0000000000401f1c in main() at codes/terrainExample.cpp:186 

Was mit meiner Implementierung falsch ist?

Im Folgenden ist der Link zu den Code und die valgrind Protokoll bei Bedarf: https://www.dropbox.com/s/5m8zfxubq6lcl8o/terrainExample.cpp?dl=0 https://www.dropbox.com/s/wq7ob1uevwutsov/logfile.out?dl=0

In diesem Code Ich verwende Vektor statt Karte.

+1

Überprüfen Sie Ihre Indexvariablen, wenn Sie mit dem Debugger durch Ihren Code gehen und sicherstellen, dass Sie auf Ihre Arrays in Grenzen zugreifen. –

+0

Linie 134 Ich mache das. bool isValid (const int x, const int y) {wenn ((x <0) || (y <0) || (x> = maxX) || (y> = maxY)) return false; true zurückgeben;} in debug auch ich überprüft. – prad

Antwort

1

Das war ein interessantes Stück Code, ich hatte wirklich Spaß beim Anschauen. Also lasst es uns sezieren.

Erstens klagt valgrind, dass:

==15718== Warning: client switching stacks? SP change: 0xfff000420 --> 0xffed6b8d8

Das mir sagt, es ist ein Stapel irgendwo Zerschlagung. durch den Code Nach dem Surfen, in der Tat gibt es große lokale Variablen auf dem Stapel gespeichert, so entweder:

  1. versuchen, die Größe des Bildes (zum Beispiel Einstellung const int maxX = 320; const int maxY = 640; fixiert das Stapelproblem) zu reduzieren
  2. Aber Wenn Sie wirklich große Bildgrößen benötigen, führen Sie einfach eine dynamische Speicherverwaltung durch.

jedoch stürzt die Anwendung noch irgendwo ... und ich finde, dass nextMove immer und immer wieder in einem Rekursion Aufruf ... na ja, wieder den Stapel stört. Also, um die Dinge besser machen, so etwas tun:

  1. Änderung nextMovevoid nextMove(const int x, const int y)-void nextMove(int x, int y). Ich habe nur die Konstante der Parameter entfernt, Sie werden in einer Minute sehen warum.
  2. ein Label hinzufügen, gerade am Anfang der Funktion:

    void nextMove(int x, int y) { again:

    und last but not least:

  3. Stattdessen rekursiv die Funktion am Ende des Aufrufs nextMove(nx, ny);, so etwas wie : x = nx; y = ny; goto again;

Einige Leute hassen mich einfach für die Verwendung von, also werde ich sie bitten, eine Antwort zu geben, die keine goto s in ihnen hat.

Hoffe, das hilft!

+0

danke @fritzone, es hat funktioniert. Ich habe alle großen Arrays geändert, um sie dynamisch zuzuordnen. goto nicht verwendet, da dies den x- und y-Wert des voreingestellten nextMove-Aufrufs geändert hätte. – prad

Verwandte Themen