#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]
, а не указателем.