Для динамического выделения 2D-массива:
char **p;
int i, dim1, dim2;
/* Allocate the first dimension, which is actually a pointer to pointer to char */
p = malloc (sizeof (char *) * dim1);
/* Then allocate each of the pointers allocated in previous step arrays of pointer to chars
* within each of these arrays are chars
*/
for (i = 0; i < dim1; i++)
{
*(p + i) = malloc (sizeof (char) * dim2);
/* or p[i] = malloc (sizeof (char) * dim2); */
}
/* Do work */
/* Deallocate the allocated array. Start deallocation from the lowest level.
* that is in the reverse order of which we did the allocation
*/
for (i = 0; i < dim1; i++)
{
free (p[i]);
}
free (p);
Изменить вышеуказанный метод. Когда вам нужно добавить еще одну строку, выполните *(p + i) = malloc (sizeof (char) * dim2);
и обновите i
. В этом случае вам нужно предсказать максимальное количество строк в файле, которое указано в переменной dim1
, для которой мы выделяем массив p
в первый раз. Это будет выделять только (sizeof (int *) * dim1)
байтов, что намного лучше, чем char p[dim1][dim2]
(в c99).
Есть другой способ, которым я думаю. Выделяйте массивы в блоки и объединяйте их в цепочки при переполнении.
struct _lines {
char **line;
int n;
struct _lines *next;
} *file;
file = malloc (sizeof (struct _lines));
file->line = malloc (sizeof (char *) * LINE_MAX);
file->n = 0;
head = file;
После этого первый блок готов к использованию. Когда вам нужно вставить строку, просто сделайте:
/* get line into buffer */
file.line[n] = malloc (sizeof (char) * (strlen (buffer) + 1));
n++;
Когда n
равен LINE_MAX
, выделите другой блок и свяжите его с этим.
struct _lines *temp;
temp = malloc (sizeof (struct _lines));
temp->line = malloc (sizeof (char *) * LINE_MAX);
temp->n = 0;
file->next = temp;
file = file->next;
Примерно так.
Когда один из блоков n
становится 0
, освободите его и обновите указатель текущего блока file
на предыдущий. Вы можете либо пройти от начала одного связанного списка и перейти от начала или использовать двойные ссылки.