Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C fprintf由于地址突然改变而导致分段错误_C_Segmentation Fault_Printf - Fatal编程技术网

C fprintf由于地址突然改变而导致分段错误

C fprintf由于地址突然改变而导致分段错误,c,segmentation-fault,printf,C,Segmentation Fault,Printf,我正在用ncurses编写一个小的控制台游戏(作为一项学习任务),我已经遇到了一些小问题(这是我第一次在C语言中使用列表),但从来没有真正的止步符。然而,作为“未来的准备”,我想实现一个基本的调试日志文件。这就是事情开始变得奇怪的地方 日志文件是全局声明的,fopen()(使用w+模式)和ferror()不显示任何错误证据。相反,一切似乎都完美无瑕,日志文件被创建,信息被写入其中。但是,在我为各种函数添加了一些调试输出之后,游戏就出现了故障。因此,我已经注释掉了文件中几乎所有的调试输出,现在这行

我正在用ncurses编写一个小的控制台游戏(作为一项学习任务),我已经遇到了一些小问题(这是我第一次在C语言中使用列表),但从来没有真正的止步符。然而,作为“未来的准备”,我想实现一个基本的调试日志文件。这就是事情开始变得奇怪的地方

日志文件是全局声明的,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
Old value = (FILE *) 0x0
New value = (FILE *) 0x62f6f0
init () at console.c:128
128     fprintf(debuglog, "init()\n\tInitialised ncurses\n");
(game.c:207是我前面提到的一行)另外,有人告诉我应该使用watch debuglog,其输出如下:

#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
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秒后(这是游戏正常结束后的时间),游戏将失败。有时,将gdb与debuglog一起用作观察点时,它也会输出

Old value = (FILE *) 0x22f6f0
New value = (FILE *) 0x0
或0x2而不是0x0。我甚至已经有了一个SIGABRT


因为我是初学者,我不知道下一步该做什么。我已经问过一些人,他们肯定有广博的知识,但他们无法找到“万恶之源”。如果你需要代码,你可以找到它。我希望这只是我犯的一个愚蠢的错误…

很可能是你在上面写的。这就是我的意思

console.c
中,您有

int field[FIELDMAXX][FIELDMAXY];
FILE * debuglog;
在更改
debuglog
的行中,您有:

field[target_ob->x_pos][target_ob->y_pos] = OBSTACLE; /* Changes debuglog. */
因此,很可能值
target\u ob->x\u pos
target\u ob->y\u pos
是您不期望的


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

因此,我找到了一个解决方案。这是我犯的一个愚蠢的错误。。。真蠢:D

比赛场地由
int field[FIELDMAXX][FIELDMAXY]宣布
,其中
FIELDMAXX
为78,
FIELDMAXY
为21。现在看一下
创建障碍物()
:新创建障碍物的坐标是
FIELDMAXX+1
get\u randypos()
(返回1到21的整数)。这是一个典型的初学者错误:在
移动障碍物()
中,有一行写着
字段[target\u ob->x\u pos][target\u ob->y\u pos]=障碍物(障碍物定义为2)


每一个障碍物每秒向左移动一个“长度单位”(
target\u ob->x\u pos--;
)。因此,如果新创建的具有
x_pos=79
(即
FIELDMAXX+1
)和
y_pos=21
的障碍物被
move_barrier()
移动,则其新的
x_pos
78(而其
y_pos
21)。因此,我上面提到的行尝试将
字段[78][21]
设置为
障碍物
——这是不可能的(超出范围)。我现在有点为自己感到羞愧:)

更有可能是一个字节被覆盖了。请注意,
debuglog
的值从
0x00062f6f0
更改为
0x20062f6f0
。(0x20是ASCII空格字符这一事实可能是一个线索。)。。。我已经找到了一个解决方案,我会尽快发布:)