No, the secondary arrays will not be freed automatically; you will need to explicitly free
them before freeing listofdetails
:
for ( i = 0; i < 6; i++ )
free( listofdetails[i] );
free( listofdetails );
For every malloc
there must be a free
, and the free
calls must be executed in the reverse order of the malloc
calls.
If the number of columns is known at compile time1, you can allocate the whole thing in one malloc
call, like so:
char (*listofdetails)[40] = malloc( sizeof *listofdetails * 6 );
This allocates a 6x40 array of char
in a single call. You'd use it pretty much the same way as you do above:
fgets( listofdetails[i], sizeof listofdetails[i], fp );
The type of listdetails[i]
is "40-element array of char
", so sizeof listdetails[i]
will give us the same result as sizeof (char) * 40
(note that this only works because I declared listofdetails
as a pointer to a 40-element array of char
, not as a pointer to a pointer to char
).
This also has the advantage that all of the rows are adjacent to each other in memory, which may matter for some situations. That's not necessarily the case for the 2-step allocation method.
This only requires a single free
call:
free( listofdetails );
but y'all probably aren't to the point of discussing pointers to arrays yet.
1. If you're using a C99 compiler or a C2011 compiler that still supports variable-length arrays, you can still use the single malloc
call like so:
size_t rows, cols;
...
char (*listofdetails[cols]) = malloc( sizeof *listofdetails * rows );
...
free( listofdetails );
Otherwise, you'll have to do the piecemeal allocation as in your code.