выделение двумерного массива символов в c

#arrays #c #malloc #allocation

#массивы #c #мэллок #распределение

Вопрос:

У меня есть структура, которая содержит сетку, а затем двумерный массив символов, потому что мне нужно смоделировать игру, в которой каждый игрок может поместить » о » или » х » в каждую ячейку. Моя структура следующая (я реализовал ее после ответа на этом веб-сайте):

 struct game {  char ** grid;   };  

Теперь в моей функции create_game я попытался реализовать ее следующим образом:

 struct game *create(int columns, int rows) {  struct game *new_game = malloc(sizeof(struct game));  if (new_game)  {   new_game-gt;grid = malloc(sizeof(char) * rows);  if (new_game-gt;grid == NULL)  {  free(new_game);  return NULL;  }  for (int i = 0; i lt; rows; i  )  {  new_game-gt;grid[i] = malloc(sizeof(char) * columns);  // set each cell to empty string  if (new_game-gt;grid[i] == NULL)  {  free(new_game-gt;grid);  free(new_game);  return NULL;  }  }  for (int i = 0; i lt; new_game-gt;rows; i  )  {  for (int j = 0; j lt; new_game-gt;columns; j  )  {  new_game-gt;grid[i][j] = ' ';  printf("%c ", new_game-gt;grid[i][j]);  }  }  }  return new_game; }  

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

Комментарии:

1. Предоставленный вами код не будет компилироваться, потому что в вашем определении есть «отсутствующие» элементы struct game .

2. Однако, если это исправлено, ваш первый malloc вызов неверен: измените new_game-gt;grid = malloc(sizeof(char) * rows); на new_game-gt;grid = malloc(sizeof(char*) * rows); , потому что для этого вам нужен массив указателей, а не массив char .

3. Зачем мне нужен массив указателей?

4. @Елена есть несколько способов создания 2D-массива. Способом, предложенным выше, вы создаете 1D массив указателей, каждый из которых указывает на 1D массив ячеек. При использовании массива этого типа вы можете использовать grid[a][b] для извлечения символа. Заглянув немного глубже, grid[a] возвращает указатель типа char * , который затем разыменовывается с помощью индекса [b] для выбора символа. Вот почему grid объявлен как char ** … указатель на массив указателей в данном случае.

5. Наконец, третьим способом было бы объявить одно измерение массива в типе указателя: char (*grid) [rowsize] = malloc(sizeof (char[row_size]) * num_rows) но это означало бы, что одно из измерений должно быть постоянным, по крайней мере, для некоторых версий языка C. Этот последний также используется как grid[a][b] , но в данном случае тип grid[a] является типом массива, char[row_size] , а не указателем.