[英]My first C program - Game of Life: printf segmentation fault
我的第一個C程序(Conway的“人生游戲”的C / C ++課程版本)遇到了問題。 我編寫了它,並使其與GCC一起編譯,但是我在嘗試追逐分段錯誤時遇到了麻煩。 具體來說,現在我的問題在打印功能中。 我也包括main(),以防問題與此相關。 我忽略了其他功能,因為我看不到它們之間的關系。
#include <stdio.h>
#define XMAX 240
#define YMAX 80
int main(int argc, char **argv) {
int cycles = 0;
char current[XMAX][YMAX];
char next[XMAX][YMAX];
//first, fill current with all spaces
int i,j;
for( j=0; j< YMAX; j++){
for( i = 0; i < XMAX; i++) {
current[i][j] = ' ';
}
}
//next, check if there are an even number of inputs
//if there are, edit those cells in current
if (argc > 1) {
if (argc % 2 != 0) {
int k;
for(k = 0; k < argc-1; k+=2) {
current[atoi(*argv[k])][atoi(*argv[k+1])] = 'O';
}
}
//otherwise, we print an error message and quit.-
else {
printf("Invalid number of command line arguments, must be even");
return;
}
}
//print starting configuration
print(current, cycles);
//start recursive update method
update(current, next, cycles);
}
令人討厭的打印功能:
// method that prints world and number of cycles
void print(char world[XMAX][YMAX], int cycles) {
printf(cycles);
printf("\n");
// iterates through world printing everything
int i;
int j;
for( j = 0; j < YMAX; j++) {
for( i = 0; i < XMAX; i++) {
printf(world[i][j]);
}
//print a new line every time we jump down a row
printf("\n");
}
}
這是調試日志。 這發生在產生任何輸出之前。
Program received signal
SIGSEGV, Segmentation fault.
0x00007ffff7aa32ba in strchrnul () from /lib64/libc.so.6
(gdb) backtrace
#0 0x00007ffff7aa32ba in strchrnul () from /lib64/libc.so.6
#1 0x00007ffff7a59cd2 in vfprintf () from /lib64/libc.so.6
#2 0x00007ffff7a64519 in printf () from /lib64/libc.so.6
#3 0x000000000040092b in print (world=0x7fffffff9210, cycles=0) at game.c:48
#4 0x000000000040088b in main (argc=1, argv=0x7fffffffde18) at game.c:34
(gdb) frame 3
#3 0x000000000040092b in print (world=0x7fffffff9210, cycles=0) at game.c:48
48 printf(world[i][j]) ;
(gdb) print i
$1 = 0
(gdb) print j
$2 = 0
(gdb) print world[i][j]
$3 = -128 '\200'
(gdb) print sizeof(world)
$4 = 8
(gdb) print sizeof(world[0])
$5 = 80
所以,有些事情我沒有。 首先,為什么我可以訪問world [i] [j]但printf無法訪問? 因為兩個索引值都仍為0,所以它不能只是出界錯誤,對嗎?
其次,-128'\\ 200'表示什么,為什么它不是空格字符? Main應該用空格填充數組,所以我可能在那弄亂了。
最后,數組的大小是怎么回事? 應該是240 x 80,那么為什么一個尺寸是80,而另一個尺寸只有8?
我敢肯定,對於某些人來說,這是令人討厭的簡單問題,請耐心等待。 我來自Java背景,因此C是可識別的,但又足以使我失望。 另外,如果需要更多信息,我可以提供。
問題可能在以下幾行:
printf(cycles);
printf(world[i][j]);
事實是, printf
的原型是:
int printf(const char *format, ...)
但是您將int
和char
作為單個參數傳遞,而不是const char *
。 這應該在編譯時發出警告。 永遠不要忽視警告!
如果您的編譯器未對這種用法提出警告,則應真正添加all-warnings-on編譯器選項(例如,在GCC中為-Wall
)。
解決方法很簡單,使用格式字符串:
printf("%d\n", cycles); // add the \n to the same format!
printf("%c", world[i][j]);
關於您的問題:
首先,為什么我可以訪問world [i] [j]但printf無法訪問? 因為兩個索引值都仍為0,所以它不能只是出界錯誤,對嗎?
調試器print
與功能printf
不相關。 調試器知道類型化表達式的聲明類型。 printf
沒有。 這就是格式字符串的用途。
其次,-128'\\ 200'表示什么,為什么它不是空格字符? Main應該用空格填充數組,所以我可能在那弄亂了。
不知道。 您正在進行段故障隔離,因此堆棧中的變量可能已損壞或其他原因。
最后,數組的大小是怎么回事? 應該是240 x 80,那么為什么一個尺寸是80,而另一個尺寸只有8?
函數內部的world
實際上不是數組,而是指針。 函數參數中的數組聲明被降級為指針,因此char world[XMAX][YMAX]
被編譯為char (*world)[YMAX]
。 因此, sizeof(world)
是指針的大小。 但是,由於world[0]
是數組的指針,所以它的類型為char[YMAX], so
sizeof(world [0]) is
YMAX`。
主要問題是您不能使用來打印單個字符
printf(world[i][j])
因為第一個參數必須是字符串。 因此,它嘗試將world [i] [j]解釋為字符串,並搜索為0的第一個字節(C中的字符串終止符),因此繼續在不允許訪問的內存區域中進行搜索(因此,segfault) 。
如果只想打印一個字符,請使用
print("%c",world[i][j])
函數printf像這樣:
int printf ( const char * format, ... );
但是您使用:
printf(world[i][j]);
您是要這樣做嗎?
printf("%d", world[i][j]);
另外,這是錯誤的:
printf(cycles);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.