Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allocate and deallocate heap memory for 2D array?

I'm used to PHP, but I'm starting to learn C. I'm trying to create a program that reads a file line by line and stores each line to an array.

So far I have a program that reads the file line by line, and even prints each line as it goes, but now I just need to add each line to an array.

My buddy last night was telling me a bit about it. He said I'd have to use a multidimensional array in C, so basically array[x][y]. The [y] part itself is easy, because I know the maximum amount of bytes that each line will be. However, I don't know how many lines the file will be.

I figure I can make it loop through the file and just increment an integer each time and use that, but I feel that there might be a more simple way of doing it.

Any ideas or even a hint in the right direction? I appreciate any help.

like image 329
Rob Avatar asked Aug 28 '11 15:08

Rob


People also ask

How do you deallocate a 2D array of pointers in C++?

To delete a 2D ordinary array, just let it go out of scope. If the 2D array is in free store, then it must be deleted with the delete[] operator to free memory in the scope in which it is declared.


1 Answers

To dynamically allocate a 2D array:

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);

Modify the above method. When you need another line to be added do *(p + i) = malloc (sizeof (char) * dim2); and update i. In this case you need to predict the max numbers of lines in the file which is indicated by the dim1 variable, for which we allocate the p array first time. This will only allocate the (sizeof (int *) * dim1) bytes, thus much better option than char p[dim1][dim2] (in c99).

There is another way i think. Allocate arrays in blocks and chain them when there is an overflow.

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;

After this the first block is ready to use. When you need to insert a line just do:

/* get line into buffer */
file.line[n] = malloc (sizeof (char) * (strlen (buffer) + 1));
n++;

When n is LINE_MAX allocate another block and link it to this one.

struct _lines *temp;

temp = malloc (sizeof (struct _lines));
temp->line = malloc (sizeof (char *) * LINE_MAX);
temp->n = 0;
file->next = temp;
file = file->next;

Something like this.

When one block's n becomes 0, deallocate it, and update the current block pointer file to the previous one. You can either traverse from beginning single linked list and traverse from the start or use double links.

like image 71
phoxis Avatar answered Sep 18 '22 22:09

phoxis