1

Im new для C, linux и т. Д. Мой код компилируется и запускается, но как только я ввожу свои первые пользовательские входы, я получаю ошибку сегментации. Если кто-то может указать, что не так с моим кодом, что было бы очень полезно, я думаю, что он либо находится в «calculate()», либо «main()», потому что я попытался выделить память, используя «malloc()» в обоих эти места.Ошибка игры в сегментировании жизни в C

#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; 
} 
+1

Скомпилируйте свою программу с параметром '-g', откройте ее внутри gdb (' gdb myprogramname'), запустите ее ('run') и распечатайте обратную трассировку после получения segfault (' bt'). –

+0

@NemanjaBoric, как именно я помещаю это в терминал, я обычно делаю gcc -Wall «ProjectName.c», а затем запускаю его с ./a.out –

+0

Если я прав, это произойдет после того, как вы ввели свою ВЫСОТУ и ШИРИНУЮ ? – xQuare

ответ

0

В главном

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

из-за этого \ п вам нужно ввести еще один input.avoid он

и ошибки сегментации в 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) 

и здесь не выделяет память, но вы получаете доступ. Сначала введите память

+0

Как я могу исправить то, что я думал, что я уже выделил память. –

+0

@MelMoore простой способ крепления объявляется глобально. 'static int table [max] [max];' и избегать передачи массива в качестве аргумента. если вы не хотите объявлять глобально, вы должны играть с указателями .... – Gangadhar

+0

Я пытался использовать указатели, но теперь я просто получаю seg-ошибки. –

0

Это SEG-разломообразования из:

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.

Вам нужно проверить, чтобы координаты были неотрицательными и были меньше, чем указанные выше размеры, когда пользователь вводит, если он не находится внутри линии, просто выкидывает сообщение об ошибке и выходит.

Вторая вещь:
Кроме того, ваша end переменный в основном не инициализирован, может быть, вы пропустили этот end = getchar() в состоянии if.
Если это не инициализировано, может также возникнуть ошибка seg.

Третья вещь:
\n в scanf действительно требуется? Если он присутствует, он будет принимать третий вход в качестве входа для следующего scanf и не будет запрашивать ввод для этого scanf.
, то есть здесь в настоящее время третий вход войдет в номер. организмов, не требующих.

+0

'\ n' хуже, чем не требуется , вам потребуется ввести строку TWICE, хотя используется только первая. – delicateLatticeworkFever

+0

Итак, я должен поставить инструкцию if в цикле for только для таблицы [] [] = жизни, только если высота и ширина> 0, но <ВЫСОТА И ШИРИНА? –

+0

Да, конечно! –