简体   繁体   中英

My first C program - Game of Life: printf segmentation fault

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM