我正在寫一個帶有ncurses的小型控制檯遊戲(作爲學習任務),並且我已經有一些小問題了(這是我第一次使用列表在C),但從來沒有一個真正的showstopper。然而,作爲「未來規定」,我想實現一個基本的調試日誌文件。而這正是事情開始表現奇怪的地方。fprintf由於突然地址更改導致段錯誤
日誌文件是全局聲明的,fopen()(使用w +模式)和ferror()不顯示任何錯誤證據。相反,一切似乎完美地工作,日誌文件被創建,信息被寫入它。然而,在我爲各種函數添加了一些調試輸出之後,遊戲只是段錯誤。作爲consquence,我已經註釋掉幾乎所有調試輸出到文件,現在這個簡單的代碼行崩潰了整場比賽:
fprintf(debuglog, "loop_game()\n\tTime's over! Returning 0\n");
我用gdb運行程序,並BT全輸出如下:
#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是我前面提到的線)。此外,有人告訴我,我應該使用手錶DEBUGLOG,其輸出是如下:
Old value = (FILE *) 0x0
New value = (FILE *) 0x62f6f0
init() at console.c:128
128 fprintf(debuglog, "init()\n\tInitialised ncurses\n");
然後我使用繼續,大約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秒之後(這是時間後遊戲應該正常結束) ,遊戲segfaults。有時觀察點用gdb與DEBUGLOG時它也輸出
Old value = (FILE *) 0x22f6f0
New value = (FILE *) 0x0
或0X2而不是爲0x0。我甚至已經有了一個SIGABRT。
由於我是初學者,我不知道下一步該怎麼做。我已經問過一些確實有廣博知識的人,但他們無法找到「萬惡之源」。如果你需要的代碼,你可以找到它here。我希望這只是我犯的一個愚蠢的錯誤...
單字節被覆蓋的可能性更大。請注意,'debuglog'的值從'0x00062f6f0'變爲'0x20062f6f0'。 (0x20是ASCII空格字符的事實*可能是線索。) –
...我找到了一個解決方案,只要我被允許這樣做,我就會發布它:) –