康威的生命游戏,Segfault 11

时间:2017-05-03 20:37:36

标签: c conways-game-of-life

我试图用C语写下康威的生活游戏。这就是我到目前为止所做的。我使用指针来引用数组,这在以前从未引起过我的问题,但函数place_cell导致了段错误。

这是我迄今为止所尝试的内容:   - 我尝试使用常量,100 x 100和10 x 10制作网格。修改    这些恒定网格中的值仍然给我一个段错误。   - 我尝试将常量用于place_cell,仍然有段错误。

int** make_grid(int x, int y) {
    int** is = (int**)malloc(sizeof(int*) * y);
    if(! is) {
        fprintf(stderr, "make_grid: malloc failed");
        exit(1);
    }
    int j;
    for(j = 0; j < y; j++) {
        is[j] = (int*)malloc(sizeof(int) * x);
        if(!is[j]) {
            fprintf(stderr, "make_grid: malloc failed");
            exit(1);
        }
    }
    return is;
}

/* takes two integers and places a cell at those coords */
void place_cell(int** is, int sidex, int sidey, int x, int y) {
    if(x >= sidex || y >= sidey) {
        fprintf(stderr, "place_cell: out of grid range\n");
        exit(1);
    }
    is[y][x] = 1;
}

int check_surroundings(int** is, int sidex,
                       int sidey, int x, int y) {
    int y_less = y - 1;
    if(y == 0) {
        y_less = sidey - 1;
    }
    int y_more = y + 1;
    if(y == sidey - 1) {
        y_more = 0;
    }
    int x_less = x - 1;
    if(x == 0) {
        x_less = sidex - 1;
    }
    int x_more = x + 1;
    if(x == sidex - 1) {
        x_more = 0;
    }
    int p = is[y_less][x_less] +
        is[y_less][x] +
        is[y_less][x_more] +
        is[y][x_less] +
        is[y][x_more] +
        is[y_more][x_less] +
        is[y_more][x_less] +
        is[y_more][x_more];
    return p;
}

void change_condition(int** is,
                      int sidex, int sidey, int x, int y) {
    int* state = &is[y][x];
    int surr = check_surroundings(is, sidex, sidey, x, y);
    if(surr > 3) {
        *state = 0;
    } else if(surr == 3 || surr == 2) {
        *state = 1;
    } else {
        *state = 0;
    }
}

void print_grid(int** is, int sidex, int sidey) {
    int i, j;
    for(i = 0; i < sidey; i++) {
        for(j = 0; j < sidex; j++) {
            if(is[i][j] == 1) {
                printf("*");
            } else {
                printf(" ");
            }
        }
        printf("\n");
    }
}

void new_generation(int** is, int sidex, int sidey) {
    int i, j;
    for(i = 0; i < sidey; i++) {
        for(j = 0; j < sidex; j++) {
            change_condition(is, sidex, sidey, j, i);
        }
    }
}

void play(int** is, int sidex, int sidey) {
    int i = 0;
    while(i < 100) {
        new_generation(is, sidex, sidey);
        print_grid(is, sidex, sidey);
        i++;
    }
}

这是我的主要内容:

int main(int argc, char* argv[]) {

    int sidex = atoi(argv[0]);
    int sidey = atoi(argv[1]);
    int** is = make_grid(10, 10);
    int i;
    for(i = 2; i < argc; i += 2) {
        place_cell(is, sidex, sidey,
                   atoi(argv[i]), atoi(argv[i + 1]));
    }

    return 0;
}

编辑:

int** make_grid(int x, int y) {
    int (*is)[x] = (int*)malloc(sizeof(int) * y * x);
    if(! is) {
        fprintf(stderr, "make_grid: malloc failed");
        exit(1);
    }
    int j;
    for(j = 0; j < y; j++) {
        is[j] = (int*)malloc(sizeof(int) * x);
        if(!is[j]) {
            fprintf(stderr, "make_grid: malloc failed");
            exit(1);
        }
    }
    return is;
}

这根本不对,但我无法理解为什么。有人可以向我解释一下我要改变的是什么吗? (一个知道C的五岁的孩子,我猜)

2 个答案:

答案 0 :(得分:0)

我刚刚复制了整个代码并试图运行该程序。内存访问冲突(至少对我而言)在这一行:

int sidex = atoi(argv[0]);
int sidey = atoi(argv[1]);    <-- memory access violation

原因是(至少在我的情况下)我刚刚运行了没有参数的程序。

现在,即使我确实在命令行上提供了参数,索引仍然是关闭的。第一个参数argv[0]是可执行文件的名称,而不是名称后面的第一个参数。

因此,您的代码需要注意以下几点:

  1. 无法保证成为参数。您应该始终查看argc以确保您可以索引argv
  2. 这些参数也不保证是整数 - 在将它们用作维度之前,你最好也检查一下
  3. 当然,对于索引转换,您也应该相应地调整“数组读取”代码。但是一旦你修复了索引,这对你来说应该很容易

答案 1 :(得分:-1)

您没有声明具有该语法的二维数组,因此内存未按您的思路对齐,因此是分段错误。声明指针int **不会使它成为二维数组。 (当然你不认为int ***会给你一个数据立方体吗?)。

Heap allocate a 2D array (not array of pointers)

上面的一条评论给出了另一个问题,C程序的零参数argv [0]是程序的名称,而不是命令行中的第一个参数,即argv [1]。