c - fprintf 因地址突然变化导致段错误

标签 c segmentation-fault printf

我正在用 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_postarget_ob->y_pos 的值很可能不是您所期望的。

现在,您要做的第一件事就是解决这个问题(找出这些坐标会发生什么)。您可以做的第二件事是定义一些其他的日志记录方式。我个人认为我会使用一个单独的日志记录函数(它会调用 vfprintf)并且我会将 debugfile 静态化到某个文件。

关于c - fprintf 因地址突然变化导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7071958/

相关文章:

从 setuid root C 程序调用脚本 - 脚本不以 root 身份运行

c - 将函数指针传递给函数+函数参数

c - Visual Studio C2085 关于数组定义

c++ - 退出 Tcl_DoOneEvent 函数

c++ - 为什么虚函数会出现段错误

c - 关于 "C Programming A Modern Approach 2nd Edition"中的printf\t

c - 'ld' 无法链接符号,尽管它们在库中

c - CC/GCC 但不是 G++ (C/SDL2/Linux) 的奇怪段错误

C - scanf 没有因用户输入而停止

java - 取消格式化字符串