简体   繁体   English

我的第一个C程序-人生游戏:printf分割错误

[英]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. 我的第一个C程序(Conway的“人生游戏”的C / C ++课程版本)遇到了问题。 I wrote it and got it to compile with GCC, but I'm getting stuck trying to chase segmentation faults. 我编写了它,并使其与GCC一起编译,但是我在尝试追逐分段错误时遇到了麻烦。 Specifically, right now my issue is in my print function. 具体来说,现在我的问题在打印功能中。 I included main() as well in case the issue is related to it. 我也包括main(),以防问题与此相关。 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? 首先,为什么我可以访问world [i] [j]但printf无法访问? It can't just be an out of bounds error since both index values are still at 0, right? 因为两个索引值都仍为0,所以它不能只是出界错误,对吗?

Secondly, what does -128 '\\200' signify, and why is it not a space character? 其次,-128'\\ 200'表示什么,为什么它不是空格字符? Main was supposed to fill the array with spaces, so I might have messed up there. Main应该用空格填充数组,所以我可能在那弄乱了。

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? 应该是240 x 80,那么为什么一个尺寸是80,而另一个尺寸只有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. 我来自Java背景,因此C是可识别的,但又足以使我失望。 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: 事实是, printf的原型是:

int printf(const char *format, ...)

but you are passing an int and a char as single arguments, not a const char * . 但是您将intchar作为单个参数传递,而不是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). 如果您的编译器未对这种用法提出警告,则应真正添加all-warnings-on编译器选项(例如,在GCC中为-Wall )。

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? 首先,为什么我可以访问world [i] [j]但printf无法访问? It can't just be an out of bounds error since both index values are still at 0, right? 因为两个索引值都仍为0,所以它不能只是出界错误,对吗?

The debugger print is not related to the function printf . 调试器print与功能printf不相关。 The debugger knows the declared type of the typed expression; 调试器知道类型化表达式的声明类型。 printf does not. printf没有。 That's what the format string is for. 这就是格式字符串的用途。

Secondly, what does -128 '\\200' signify, and why is it not a space character? 其次,-128'\\ 200'表示什么,为什么它不是空格字符? Main was supposed to fill the array with spaces, so I might have messed up there. Main应该用空格填充数组,所以我可能在那弄乱了。

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? 应该是240 x 80,那么为什么一个尺寸是80,而另一个尺寸只有8?

world inside the function is not actually an array, but a pointer. 函数内部的world实际上不是数组,而是指针。 Array declarations in function arguments are demoted to pointers, so char world[XMAX][YMAX] gets compiled as char (*world)[YMAX] . 函数参数中的数组声明被降级为指针,因此char world[XMAX][YMAX]被编译为char (*world)[YMAX] Thus, sizeof(world) is the size of a pointer. 因此, sizeof(world)是指针的大小。 However, since it is a pointer to an array, world[0] is of type char[YMAX], so sizeof(world[0]) is YMAX`. 但是,由于world[0]是数组的指针,所以它的类型为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). 因此,它尝试将world [i] [j]解释为字符串,并搜索为0的第一个字节(C中的字符串终止符),因此继续在不允许访问的内存区域中进行搜索(因此,segfault) 。

If you only want to print a single char, use 如果只想打印一个字符,请使用

print("%c",world[i][j])

The function printf is like this: 函数printf像这样:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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