2016-08-18 73 views
-1

我试图实现以下功能。 它是做什么的:我无法理解为什么这段代码给出了段错误

  1. 需要坐标。
  2. 将权重分配给周围的单元格。
  3. 在地图中存储这些权重和单元格方向。
  4. 通过地图循环。从最低的重量开始。
  5. 调用再次移动邻居单元坐标。

代码片段:

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 } 

回溯信息:

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 

什么是错我的执行?

以下是链接到代码和Valgrind的日志如果需要的话: https://www.dropbox.com/s/5m8zfxubq6lcl8o/terrainExample.cpp?dl=0 https://www.dropbox.com/s/wq7ob1uevwutsov/logfile.out?dl=0

在这段代码中我使用矢量地图代替的。

+1

使用调试器检查代码时检查您的索引变量,并确保您访问数组的边界。 –

+0

第134行我正在那样做。 bool isValid(const int x,const int y){if((x <0)||(y <0) || (x> = maxX)||(y> = maxY))return false;返回true;} 在调试也我检查。 – prad

回答

1

这是一段有趣的代码,我真的很开心看着它。所以我们来剖析它。

首先,Valgrind的抱怨,即:

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

这告诉我有一个堆栈溢出的地方。通过代码浏览后,确实有存储在堆栈上巨大的局部变量,因此,无论是:

  1. 尽量减少图像的大小(例如设置 const int maxX = 320; const int maxY = 640;修复堆栈问题)
  2. 但如果您确实需要大图像大小,只需执行动态内存管理即可。

但是,应用程序仍然崩溃的地方......我发现,在递归调用nextMove一遍又一遍......嗯,再次扰乱堆栈。所以,把事情做好,做这样的事情:

  1. 变化nextMovevoid nextMove(const int x, const int y)void nextMove(int x, int y)。我只是删除了参数的常量,你会在一分钟内看到为什么。
  2. 添加一个标签,只是在函数的开头:

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

    以及最后但并非最不重要的:

  3. 而不是调用递归函数末nextMove(nx, ny);的,像做:x = nx; y = ny; goto again;

有些人只会恨我使用goto,所以我会要求他们提供一个答案,其中没有任何goto

希望这会有所帮助!

+0

谢谢@fritzone,它工作。我改变了所有的大数组以获得动态分配。没有使用goto,因为它会改变预设nextMove调用的x和y值。 – prad

相关问题