我无法理解为什么这段代码会出现分段错误

i'm unable to understand why this block of code is giving segmentation fault

本文关键字:代码 错误 分段 为什么 段代码      更新时间:2023-10-16

我试图实现以下功能。它的作用是:

  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=0https://www.dropbox.com/s/wq7ob1uevwutsov/logfile.out?dl=0

在这段代码中,我使用vector代替map

这是一段有趣的代码,我看得很开心。让我们来剖析一下。

首先,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的答案。

希望这对你有帮助!