Динамически выделить строковую матрицу в C - PullRequest
1 голос
/ 12 февраля 2012

Я пытаюсь прочитать карту из текстового файла и создать массив строк в соответствии с количеством строк и столбцов на карте.Каждая ячейка в сетке представляет собой строку из 2 символов.

Например,

**--**--**--
--**--**--**

должно создать матрицу 2 * 6.Количество строк и столбцов - ROWS и COLS соответственно.Я использовал

char ***map = malloc(ROWS * sizeof(char *));
for (i = 0; i < ROWS; i++) 
{
    map[i] = malloc(COLS * sizeof(char) *  2);
}

Но когда я пытаюсь использовать map[x][y], он будет зависать.

Ответы [ 5 ]

1 голос
/ 12 февраля 2012

Это может выглядеть так:

int i, j, ROWS = 2, COLS = 6;
char ***map = malloc(ROWS * sizeof(char **));
for (i = 0; i < ROWS; ++i)
{
   map[i] = malloc(COLS * sizeof(char*));
   for (j = 0; j < COLS; ++j)
      map[i][j] = malloc(2 * sizeof(char));
}

Обратите внимание, что 2 char s позволяют вам хранить эти символы, но это может вызвать некоторые проблемы, если вы собираетесь работать с ними в виде строки (printf("%s, strcpy ...). В этом случае я бы предпочел выделить память на 3 char с, чтобы можно было также сохранить символ завершения.

Также обратите внимание, что вы должны очистить эту память, как только она будет выделена, и очистка должна быть выполнена в обратном порядке в соответствии с распределением. Это может выглядеть так:

for (i = 0; i < ROWS; ++i)
{
   for (j = 0; j < COLS; ++j)
      free(map[i][j]);
   free(map[i]);
}
free(map);

Надеюсь, это поможет.

1 голос
/ 12 февраля 2012

char ***map; можно интерпретировать как «массив массивов строк», поэтому внутренний массив фактически содержит указатели на символы.Следовательно, ваш цикл должен выглядеть следующим образом:

for(i = 0; i < ROWS; i++) {
    int j;

    map[i] = malloc(COLS * sizeof(char*));
    for(j = 0; j < COLS; j++) map[i][j] = malloc(3 * sizeof(char)); // 3 chars because a string has to be terminated by \0
}

В качестве альтернативы вы можете объявить map как char **map, тогда ваш код инициализации будет работать, но тогда вам нужно будет использовать map[i][j] и map[i][j+1] для доступа к элементам отдельных ячеек.

0 голосов
/ 12 февраля 2012

Первая строка должна быть:

char **map = malloc(ROWS * sizeof(char *));

Как правило, добавьте один * к возвращаемому типу malloc ().Если вы выделите массив из пяти целых чисел с malloc(5 * sizeof(int)), вы получите int *.

Или вы можете думать о каждом * как о добавлении измерения - char * представляет собой 1-D массив символов, а char ** - это двумерный массив.

0 голосов
/ 12 февраля 2012

Это должно быть

char ***map = malloc(ROWS * sizeof(char**));
for (i = 0; i < ROWS; i++) 
{
   map[i] = malloc(COLS * sizeof(char*));
   for (int j=0; i<COLS; ++j)
      map[i][j] = malloc(3*sizeof(char);
}

Редактировать: Как указано в другом ответе и комментарии, должно быть 3, а не 2 malloc'ed символа.

0 голосов
/ 12 февраля 2012

Если вы хотите 2D массив, как вы объявляете map как char***? Измените его на char**.

(Если я неправильно понял, и вам нужен 2D-массив char*, вы должны изменить распределение, чтобы использовать sizeof(char**) и sizeof(char*), и выделить память для строки отдельно.)

Редактировать: Если вы знаете размер карты при объявлении, сделайте ее char map[ROWS][COLS][2]; Если вы этого не сделаете (или вы просто хотите передать его другим функциям), вы можете объявить его как char (**map)[2] и сохранить ваши выделения как есть.

(Измените 2 на 3, если вы хотите прекратить их на \0 (например, для его печати))

...