我遇到了我的第一个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
所以,有一些我没有得到的东西。首先,为什么我可以访问世界[i] [j]但printf不能?它不仅仅是一个越界错误,因为两个索引值仍然是0,对吗?
其次,-128'\ 200'表示什么,为什么它不是空格字符? Main应该用空格填充数组,所以我可能搞乱了。
最后,数组的大小是怎么回事?它应该是240 x 80,所以为什么一个尺寸80但另一个只有8?
对于你们中的一些人,我确信这些是令人作呕的简单问题,所以请耐心等待。我来自一个java背景,所以C是可识别的,但只是不同,足以让我失望。此外,如果需要更多信息,我可以提供。
答案 0 :(得分:3)
问题很可能在以下几个方面:
printf(cycles);
printf(world[i][j]);
问题是printf
的原型是:
int printf(const char *format, ...)
但您传递int
和char
作为单个参数,而不是const char *
。这应该在编译时发出警告。永远不要忽视警告!
如果您的编译器没有警告这种用法,您应该在GCC中添加all-warnings-on编译器选项(-Wall
)。
解决方案很简单,使用格式字符串:
printf("%d\n", cycles); // add the \n to the same format!
printf("%c", world[i][j]);
关于您的问题:
首先,为什么我可以访问世界[i] [j]但是printf不能?它不能只是一个越界错误,因为两个索引值仍然是0,对吗?
调试器print
与函数printf
无关。调试器知道类型化表达式的声明类型; printf
没有。这就是格式字符串的用途。
其次,-128'\ 200'表示什么,为什么它不是空格字符? Main应该用空格填充数组,所以我可能搞乱了。
不知道。你是segfaulting,所以堆栈中的变量可能已损坏或其他。
函数内部的最后,数组的大小是怎么回事?它应该是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`。
答案 1 :(得分:1)
主要问题是您无法使用
打印单个字符printf(world[i][j])
因为第一个参数必须是一个字符串。所以它试图将world [i] [j]解释为字符串并搜索第一个字节为0(C中的字符串终止符),因此继续搜索不允许访问的内存区域(因此是段错误)
如果您只想打印一个字符,请使用
print("%c",world[i][j])
答案 2 :(得分:0)
函数printf是这样的:
int printf ( const char * format, ... );
但你使用:
printf(world[i][j]);
你的意思是这样做:
printf("%d", world[i][j]);
另外,这是错误的:
printf(cycles);