6
0x004069f1 in Space::setPosition (this=0x77733cee, x=-65, y=-49) at space.h:44    
0x00402679 in Checkers::make_move (this=0x28cbb8, move=...) at checkers.cc:351
0x00403fd2 in main_savitch_14::game::make_computer_move (this=0x28cbb8) at game.cc:153
0x00403b70 in main_savitch_14::game::play (this=0x28cbb8) at game.cc:33
0x004015fb in _fu0___ZSt4cout () at checkers.cc:96
0x004042a7 in main () at main.cc:34

您好,我正在为一门课编写游戏,但遇到了段错误。棋盘格被保存在一个二维数组中,因此有问题的位对于数组来说似乎是无效的 x/y。移动作为字符串传递,这些字符串被转换为整数,因此对于 x 和 y 不知何故为 ASCII NULL。我注意到在函数调用 make_move 中它说 move=...

为什么它说 move=...?另外,还有其他解决段错误的快速提示吗?我对 GDB 有点陌生。

4

2 回答 2

8

基本上,回溯是导致崩溃的调用的跟踪。在这种情况下:

game::play调用game::make_computer_movewhich 调用Checkers::make_movewhich call Space::setPositionwhich 在 file 的第 44 行崩溃space.h

看看这个回溯,看起来你通过了-65-49Space::setPosition如果它们碰巧是无效的坐标(在我看来肯定是消极的和所有的)。然后,您应该查看调用函数以了解它们为什么具有它们所做的值并更正它们。

我建议assert在代码中大量使用来强制执行合同,几乎任何时候你都可以说“这个参数或变量应该只具有符合某些标准的值”,那么你应该断言它就是这种情况。

一个常见的例子是,如果我有一个函数接受一个不允许的指针(或更可能是智能指针)NULL。我将拥有函数的第一行assert(p);。如果NULL指针被传递,我马上就知道并且可以调查。

最后,在 gdb 中运行应用程序,当它崩溃时。键入up以检查调用堆栈帧并查看变量的样子:(您通常可以print x在控制台中编写类似的内容)。同样,down如果您需要,也会向下移动调用堆栈。

至于SEGFAULT,我建议在valgrind中运行应用程序。如果您使用调试信息进行编译-g,那么它通常可以告诉您导致错误的代码行(甚至可以捕获由于不幸原因没有立即崩溃的错误)。

于 2012-06-02T03:11:55.413 回答
3

我不允许发表评论,但只是想回复任何最近关注该问题的人,试图找到变量的位置(-65,-49)。如果您遇到段错误,您可以获得核心转储。是确保您可以设置 gdb 以获取核心转储的一个很好的来源。然后你可以用 gdb 打开你的核心文件:

gdb -c myCoreFile

然后在你想要进入的函数调用上设置一个断点:

b MyClass::myFunctionCall

然后通过 next 或 step 逐步执行代码行:

step

或者

next

当您在代码中想要评估变量的位置时,您可以打印它:

p myVariable 

或者您可以打印所有参数:

info args

我希望这可以帮助其他想要调试的人!

于 2018-12-19T17:07:39.430 回答