Let's say we have:
void createMultiArray(){
int i,j;
char*** codes = malloc(5 * sizeof(char**));
for ( i = 0; i <= 4; i++ ) {
codes[i] = malloc((i+1) * sizeof(char*));
for ( j = 0; j <= i; j++ ) {
codes[i][j] = malloc(2 * sizeof(char));
}
}
How should I free codes
?
free(codes);
or
int i,j;
for(i = 0; i <=4; i++){
for(j = 0; j <= i; j++){
free(codes[i][j]);
}
free(codes[i]);
}
free(codes);
Think about it this way - you should have a free
for every malloc
.
// you're allocating memory for codes
// must be freed with free(codes);
char*** codes = malloc(5 * sizeof(char**));
for ( i = 0; i <= 4; i++ ) {
// allocating memory for every element in codes
// must be freed with free(codes[i]);
codes[i] = malloc((i+1) * sizeof(char*));
for ( j = 0; j <= i; j++ ) {
// allocating memory for every element in every element in codes
// must be freed with free(codes[i][j])
codes[i][j] = malloc(2 * sizeof(char));
}
}
So yes, your second option is the correct one.
The second one is what you want, free
can't and won't work recursively. Each time when you do a malloc
think of the place where you're going to call free
.
As a side note, don't free the memory if the next thing you'll do is exit the program - it's pointless and could take quite a bit of time.
The second is correct, while the first one leaks memory. As a rule of thumb, you want to call free()
for every malloc()
call.
Preferably you don't use nested malloc()-s, if you can calculate the size of the array beforehand. You should allocate and free in one step ( making your life easier and reducing the chance of bugs ).
The memory layout for createMultiArray()
would be as follows:
codes[i] codes[i][j]
*** ** *
+-+ +-+ +-+-+
|0|-------->| |----------->| | |
+-+ +-+ +-+-+
|1|-----+ | |
+-+ | +-+ | |
|2| +-->| | | +------------- char
+-+ +-+ +--------------- char
|3| | +
+-+ +-+
|4|
+-+ .... ....
Now, go back and free each memory you've created using free [yeah, for each malloc()
there should be a free()
]
OTOH, are you sure you want to do this?
for ( i = 0; i <= 4; i++ ) {
codes[i] = malloc((i+1) * sizeof(char*));
....
}
for i=0, malloc will create 1 memory cell
for i=1, malloc will create 2 memory cell
for i=2, malloc will create 3 memory cell
for i=3, malloc will create 4 memory cell
for i=4, malloc will create 5 memory cell
Is this intentional?
Don't use such complicated allocation schemes to emulate multidimensional arrays. In your case in particular, where all bounds are compile time constants.
char (*codes)[n][m] = malloc(sizeof(char[x][n][m]));
fulfills the same purpose and only needs one
free(codes);
at the end. If the context where you use that array is even bound to one scope and your bounds are small you could even allocate it directly as auto
variable and even initialize it at the same time
char codes[23][2][5] = { { { 'a', 'b'} } };
no need to free at the end.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.