簡體   English   中英

C中的生命細分錯誤博弈

[英]Game of Life Segmentation Fault in C

對於C,Linux等而言,我是新手,我的代碼可以編譯並運行,但是一旦我輸入第一個用戶輸入,就會遇到分段錯誤。 如果有人指出我的代碼出了什么問題,這將非常有幫助,我認為這是在“ calculate()”或“ main()”中,因為我試圖在兩個方面都使用“ malloc()”來分配內存那些地方。

#include <stdio.h>
#include <stdlib.h>

#define LIFE_YES 'X'
#define LIFE_NO 'O'

int HEIGHT, WIDTH;
typedef int **TableType;

void printTable(TableType table) {
    int height, width;

        for (height = 0; height < HEIGHT; height++) {
            for (width = 0; width < WIDTH; width++) {
                    if (table[height][width] == LIFE_YES) {
                        printf("X");
                    } 
            else {
                    printf("-");
                    }
            }
            printf("\n");
        }
        printf("\n");
}

void clearTable(TableType table) {
    int height, width;

        for (height = 0; height < HEIGHT; height++) {
            for (width = 0; width < WIDTH; width++) {
                    table[height][width] = LIFE_NO;
            }
        }
}

void askUser(TableType tableA) {
    int i;
        int n;
        int height, width;

        printf("Enter the amount of initial organisms: ");
        scanf("%d", &n);

        for (i = 0; i < n; i++) {
            printf("Enter dimensions (x y) where organism %d will live: ", i + 1);
            scanf("%d %d", &height, &width);

            tableA[height][width] = LIFE_YES;
        }

        printTable(tableA);
        printf("Generation 0");
}

int getNeighborValue(TableType table, int row, int col) {
        if (row < 0 || row >= HEIGHT || col < 0 || col >= WIDTH || table[row][col] != LIFE_YES ) {
            return 0;
        } 
    else {
            return 1;
        }
}

int getNeighborCount(TableType table, int row, int col) {
        int neighbor = 0;

        neighbor += getNeighborValue(table, row - 1, col - 1);
        neighbor += getNeighborValue(table, row - 1, col);
        neighbor += getNeighborValue(table, row - 1, col + 1);
        neighbor += getNeighborValue(table, row, col - 1);
        neighbor += getNeighborValue(table, row, col + 1);
        neighbor += getNeighborValue(table, row + 1, col - 1);
        neighbor += getNeighborValue(table, row + 1, col);
        neighbor += getNeighborValue(table, row + 1, col + 1);

        return neighbor;
}

void calculate(TableType tableA) {
        TableType tableB;
        int neighbor, height, width, i;
    tableB= malloc(HEIGHT * sizeof(int*));

    for (i = 0; i < HEIGHT; i++) {
            tableB[i] = malloc(WIDTH * sizeof(int));
    }

        for (height = 0; height < HEIGHT; height++) {
            for (width = 0; width < WIDTH; width++) {
                    neighbor = getNeighborCount(tableA, height, width);
                    if (neighbor==3) {
                        tableB[height][width] = LIFE_YES;
                    } 
            else if (neighbor == 2 && tableA[height][width] == LIFE_YES) {
                        tableB[height][width] = LIFE_YES;
                    } 
            else {
                        tableB[height][width] = LIFE_NO;
                    }
            }
        }

        for (height = 0; height < HEIGHT; height++) {
            for (width = 0; width < WIDTH; width++) {
                    tableA[height][width] = tableB[height][width];
            }
    }
    free(tableB);
}

/* test data
void loadTestData(TableType table) {
        table[3][4] = LIFE_YES;
        table[3][5] = LIFE_YES;
        table[3][6] = LIFE_YES;

        table[10][4] = LIFE_YES;
        table[10][5] = LIFE_YES;
        table[10][6] = LIFE_YES;
        table[11][6] = LIFE_YES;
        table[12][5] = LIFE_YES;
}
*/

int main(void) {
    int i;
        char end;
        int generation = 0;

    printf("Enter the amount of rows and columns you want in the grid: ");
    scanf("%i %i\n", &HEIGHT, &WIDTH);

        TableType table = malloc(HEIGHT * sizeof(int*));

    for (i = 0; i < HEIGHT; i++) {
            table[i] = malloc(WIDTH * sizeof(int));
    }

        clearTable(table);
        askUser(table);
        /*loadTestData(table);*/
        printTable(table);

        while (end != 'q') {
            calculate(table);
            printTable(table);
            printf("Generation %d\n", ++generation);
            printf("Press q to quit or 1 to continue: ");
            scanf(" %c", &end);
        }

        return 0;
}

在主要

scanf("%i %i\n", &HEIGHT, &WIDTH);  ==>    scanf("%i %i", &HEIGHT, &WIDTH);
             ^

因此\\ n您需要再輸入一個。避免輸入

askUser細分錯誤

tableA[height][width] = LIFE_YES;

Program received signal SIGSEGV, Segmentation fault.
0x00000000004007c1 in askUser (tableA=0x603010) at seg3.c:49
49                  tableA[height][width] = LIFE_YES;
(gdb) bt
#0  0x00000000004007c1 in askUser (tableA=0x603010) at seg3.c:49
#1  0x0000000000400bf3 in main () at seg3.c:142
(gdb)  

在這里您沒有分配內存,但是您正在訪問。首先分配內存

出現段錯誤是因為:

for (i = 0; i < n; i++) 
{
   printf("Enter dimensions (x y) where organism %d will live: ", i + 1);
   scanf("%d %d", &height, &width);
    tableA[height][width] = LIFE_YES;  <--- Here 
}

如果用戶指定的維度超出了您最初在main動態分配的'HEIGHT'和'WEIGHT'維度的范圍,該怎么辦?

當用戶輸入時,您需要檢查坐標是否為負數並且小於上述尺寸,如果不在范圍之內,則拋出錯誤消息並退出。

第二件事:
另外,main中的end變量未初始化,也許您在if條件中錯過了end = getchar()
如果未初始化,也可能導致段故障。

第三件事:
\\n是否真的需要scanf 如果存在,它將第三個輸入作為下一個scanf的輸入,並且不會提示您輸入該scanf的輸入。
也就是說,當前第三個輸入將進入“否”。 沒有提示的生物體。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM