The general procedure for dynamically allocating a 2D array of char *
is something like this (for any other type T, replace char *
with the desired type):
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;
}
This assumes you know how many rows and columns you want ahead of time. Note that you have allocated a table of pointers; you will still have to allocate memory for each string entry, like so:
char **myArr = new2DArr(10, 10);
myArr[0][0] = malloc(strlen("Hello, World") + 1);
if (myArr[0][0])
{
strcpy(myArr[0][0], "Hello, World");
}
If you want to add new rows or new entries to existing rows, you're going to have to do some extra bookkeeping.
Here's one example that extends a single row:
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;
}
And you'd call it like
table[i] = extendRow(table[i], "This is a test", &entryCount);
The result is assigned back to table[i]
in the event that the pointer value is changed by realloc()
. I'm doing it this way instead of passing a pointer to table[i] just to keep the pointer gymnastics to a minimum.