Общая процедура динамического выделения двумерного массива char *
выглядит примерно так (для любого другого типа T замените char *
на нужный тип):
char ***new2DArr(size_t rows, size_t cols)
{
char ***newArr = NULL;
size_t i;
newArr = malloc(sizeof *newArr * rows);
if (newArr)
{
for (i = 0; i < rows; i++)
{
newArr[i] = malloc(sizeof *newArr[i] * cols);
if (newArr[i])
{
/* initialize or assign newArr[i][0] - newArr[i][cols-1] here */
}
}
}
return newArr;
}
Предполагается, что вы знаете, сколько строк и столбцов вы хотите заблаговременно. Обратите внимание, что вы выделили таблицу указателей; вам все равно придется выделить память для каждой строковой записи, например:
char **myArr = new2DArr(10, 10);
myArr[0][0] = malloc(strlen("Hello, World") + 1);
if (myArr[0][0])
{
strcpy(myArr[0][0], "Hello, World");
}
Если вы хотите добавить новые строки или новые записи в существующие строки, вам нужно будет провести дополнительную бухгалтерию.
Вот один пример, который расширяет одну строку:
char **extendRow(char **row, char *newEntry, size_t *numEntries)
{
char **tmp = realloc(row, *numEntries + 1);
if (tmp)
{
row = tmp;
row[*numEntries] = malloc(strlen(newEntry) + 1);
if (row[*numEntries])
{
strcpy(row[*numEntries], newEntry);
(*numEntries)++;
}
}
return row;
}
И вы бы назвали это как
table[i] = extendRow(table[i], "This is a test", &entryCount);
Результат присваивается обратно table[i]
в случае, если значение указателя изменяется на realloc()
. Я делаю это таким образом, вместо того, чтобы передавать указатель на таблицу [i], просто чтобы минимизировать гимнастику указателя.