我正在用 ncurses 编写一个小型控制台游戏(作为一项学习任务),我已经遇到了一些小问题(这是我第一次在 C 中使用列表),但从来没有真正的表演者。然而,作为“ future 的准备”,我想实现一个基本的调试日志文件。这就是事情开始变得奇怪的地方。
日志文件是全局声明的,fopen()(使用 w+ 模式)和 ferror() 不显示任何错误证据。相反,一切似乎都完美无缺,日志文件已创建,信息已写入其中。然而,在我为各种功能添加了一些调试输出后,游戏就出现了段错误。结果,我注释掉了文件中几乎所有的调试输出,现在这行简单的代码导致整个游戏崩溃:
fprintf(debuglog, "loop_game()\n\tTime's over! Returning 0\n");
我已经使用 gdb 运行程序,bt full 输出如下:
#0 0x00007ffff7886f24 in fwrite () from /lib/libc.so.6
No symbol table info available.
#1 0x000000000040224f in loop_game (pl=0x62d800, list_win=0x62f930,
timer=0x632620, list_ob=0x632640) at game.c:207
elapsed = 60
#2 0x0000000000402d53 in main () at main.c:62
pl = 0x62d800
list_win = 0x62f930
timer = 0x632620
list_ob = 0x632640
(game.c:207 是我之前提到的那行)另外,有人告诉我应该使用watch debuglog,它的输出如下:
Old value = (FILE *) 0x0
New value = (FILE *) 0x62f6f0
init () at console.c:128
128 fprintf(debuglog, "init()\n\tInitialised ncurses\n");
然后我使用了continue,大约 10 秒后,它打印出这些行:
Old value = (FILE *) 0x62f6f0
New value = (FILE *) 0x20062f6f0
move_obstacle (win_game=0x62f970, target_ob=0x63ce00) at game.c:370
370 wrefresh(win_game);
然后,60 秒后(这是游戏正常结束后的时间),游戏出现段错误。有时,当使用带有 debuglog 作为观察点的 gdb 时,它也会输出
Old value = (FILE *) 0x22f6f0
New value = (FILE *) 0x0
或 0x2 而不是 0x0。我什至已经有一个 SIGABRT。
因为我是初学者,所以我不知道下一步该做什么。我已经问过一些绝对有广博知识的人,但他们无法找到“万恶之源”。如果您需要代码,可以找到它 here .我希望这只是我犯的一个愚蠢的错误......
最佳答案
您可能正在覆盖它。这就是我的意思。
在 console.c
中,您有
int field[FIELDMAXX][FIELDMAXY];
FILE * debuglog;
在更改 debuglog
的那一行你有:
field[target_ob->x_pos][target_ob->y_pos] = OBSTACLE; /* Changes debuglog. */
所以 target_ob->x_pos
和 target_ob->y_pos
的值很可能不是您所期望的。
现在,您要做的第一件事就是解决这个问题(找出这些坐标会发生什么)。您可以做的第二件事是定义一些其他的日志记录方式。我个人认为我会使用一个单独的日志记录函数(它会调用 vfprintf
)并且我会将 debugfile
静态化到某个文件。
关于c - fprintf 因地址突然变化导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7071958/