I'm having issues with my first C program, a version of Conway's Game of Life for my C/C++ course. I wrote it and got it to compile with GCC, but I'm getting stuck trying to chase segmentation faults. Specifically, right now my issue is in my print function. I included main() as well in case the issue is related to it. I left out the other functions as I don't see how they'd be relevant.
#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);
}
The offending print function:
// 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");
}
}
Here's the log from debugging. This happens before any output is produced.
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
So, there's a few things I don't get. First, why I can access world[i][j] but printf can't? It can't just be an out of bounds error since both index values are still at 0, right?
Secondly, what does -128 '\\200' signify, and why is it not a space character? Main was supposed to fill the array with spaces, so I might have messed up there.
Finally, what's going on with the size of the arrays? It's supposed to be 240 x 80, so why is one size 80 but the other is only 8?
I'm sure these are nauseatingly simple questions for some of you, so bear with me. I'm coming from a java background, so C is recognizable but just different enough to throw me off. Also, if more information is required, I can provide it.
The problem is likely in these lines:
printf(cycles);
printf(world[i][j]);
The thing is that the prototype of printf
is:
int printf(const char *format, ...)
but you are passing an int
and a char
as single arguments, not a const char *
. This should have emitted a warning at compile time. Never ignore a warning!
If your compiler is not warning about this usage you should really add the all-warnings-on compiler option ( -Wall
in GCC, for example).
The solution is easy, use a format string:
printf("%d\n", cycles); // add the \n to the same format!
printf("%c", world[i][j]);
About your question:
First, why I can access world[i][j] but printf can't? It can't just be an out of bounds error since both index values are still at 0, right?
The debugger print
is not related to the function printf
. The debugger knows the declared type of the typed expression; printf
does not. That's what the format string is for.
Secondly, what does -128 '\\200' signify, and why is it not a space character? Main was supposed to fill the array with spaces, so I might have messed up there.
No idea. You are segfaulting, so the variables in the stack may be corrupted or something.
Finally, what's going on with the size of the arrays? It's supposed to be 240 x 80, so why is one size 80 but the other is only 8?
world
inside the function is not actually an array, but a pointer. Array declarations in function arguments are demoted to pointers, so char world[XMAX][YMAX]
gets compiled as char (*world)[YMAX]
. Thus, sizeof(world)
is the size of a pointer. However, since it is a pointer to an array, world[0]
is of type char[YMAX], so
sizeof(world[0]) is
YMAX`.
The main problem is that you can not print a single character by using
printf(world[i][j])
because the first argument has to be a string. So it tries to interpret world[i][j] as string and searches for the first byte that is 0 (the string terminator in C) and therefore continues the search in memory areas that it is not allowed to access (therefore the segfault).
If you only want to print a single char, use
print("%c",world[i][j])
The function printf is like this:
int printf ( const char * format, ... );
But you use:
printf(world[i][j]);
Did you mean to do it like this:
printf("%d", world[i][j]);
Also, this is wrong:
printf(cycles);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.