C: Correctly freeing memory of a multi-dimensional array?

OK, there's a fair deal of confusion explaining exactly what order the necessary free() calls have to be in, so I'll try to clarify what people are trying to get at and why.

Up vote 6 down vote favorite share g+ share fb share tw.

Update (Solution) Thanks to Tim's (and the others) answer, I can now do such a function to free up memory from my multi-dimensional array : void freeArray(int **a, int m) { int i; for (i = 0; I.

1 Terminology quibble: this is not what C usually calls a "multidimensional array". It's just the only way to use the syntax aij, while still allowing both dimensions to be unknown at compile time. The other kind of multidimensional array an array of arrays, instead of this array of pointers to (the first elements of) arrays.

– Steve Jessop Nov 14 '09 at 18:12.

OK, there's a fair deal of confusion explaining exactly what order the necessary free() calls have to be in, so I'll try to clarify what people are trying to get at and why. Starting with the basics, to free up memory which has been allocated using malloc(), you simply call free() with exactly the pointer which you were given by malloc(). So for this code: int **a = malloc(m * sizeof(int *)); you need a matching: free(a); and for this line: ai=malloc(n * sizeof(int)); you need a matching: free(ai); inside a similar loop.

Where this gets complicated is the order in which this needs to happen. If you call malloc() several times to get several different chunks of memory, in general it doesn't matter what order you call free() when you have done with them. However, the order is important here for a very specific reason: you are using one chunk of malloced memory to hold the pointers to other chunks of malloced memory.

Because you must not attempt to read or write memory once you have handed it back with free(), this means that you are going to have to free the chunks with their pointers stored in ai before you free the a chunk itself. The individual chunks with pointers stored in ai are not dependent on each other, and so can be freed in whichever order you like. So, putting this all together, we get this: for (i = 0; I The compiler knows that a is an int **, so it can determine that sizeof(*a) is the same as sizeof(int *).

However, if later on you change your mind and want chars or shorts or longs or whatever in your array instead of ints, or you adapt this code for later use in something else, you will have to change just the one remaining reference to int in the first quoted line above, and everything else will automatically fall into place for you. This removes the likelihood of unnoticed errors in the future. Good luck!

1 Excellent answer; thanks for explaining the issue about the'reverse order' and also the point about the doing sizeof(*a) – Andreas Grech Nov 14 '09 at 11:08 You're welcome. Feel free to accept it when you're ready.... :-) – Tim Nov 14 '09 at 11:12 1 Also, please correct me if I'm wrong, but would I be correct in saying that sizeof(*ai) is equivalent to your sizeof(*(ai)), since the array notation have higher precedence than *? – Andreas Grech Nov 14 '09 at 11:14 No, I think you're right.

En.wikipedia.org/wiki/… However, I work on a rule of thumb that if I have to look it up, probably others reading my code would have to look it up as well, so to save them (and me, later) trouble, explicitly using brackets helps to clarify things and save time. That's just a personal preference, though. – Tim Nov 14 '09 at 11:19.

Undo exactly what you allocated: for (i = 0; I.

2 Saying that you have to free in reverse order might be misleading. You just have to free the array of pointers after the pointers themselves. – Andomar Nov 14 '09 at 10:22 Isn't that another way of saying reverse?

– GManNickG Nov 14 '09 at 10:35 2 I think @Andomar means it doesn't matter what order you free the ai's in, just that you have to free all of them before freeing a. In other words, you can free a0 thru am-1 or am-1 thru a0 or all the even a's followed by the odds. But I'm also certain @GregH didn't mean you had to do the a's in reverse order, especially given his code.

– paxdiablo Nov 14 '09 at 10:51.

You need to iterate again the array and do as many frees as mallocs for the pointed memory, and then free the array of pointers. For (i = 0; I.

Write your allocation operators in exactly reversed order, changing function names, and you'll be all right. //Free the arrays for (i = m-1; I >= 0; i--) { free(ai); } free(a); Of course, you don't have to deallocate in the very same reversed order. You just have to keep track on freeing same memory exactly once and not "forgetting" pointers to allocated memory (like it would have been if you free'd the a first).

But deallocating in the reverse order is a good role of thumb to address the latter. As pointed by litb in the comments, if allocation/deallocation had side-effects (like new/delete operators in C++), sometimes the backward order of deallocation would be more important than in this particular example.

– user181548 Nov 14 '09 at 10:20 Because a1 was allocated after a0, so you should deallocate a1 first. – Pavel Shved Nov 14 '09 at 10:21 Why do you need to free a1 before a0? They are different malloced chunks, there is no dependency between them – Arkaitz Jimenez Nov 14 '09 at 10:25 2 Since free is without side effects in C (regarding your own program code), it doesn't seem to matter much.

The "do it in reverse" rule is more important for languages that have a side effect attached to free and alloc, like C++ with its destructors/constructors. – Johannes Schaub - litb Nov 14 '09 at 10:57 2 I'm pretty sure most people would release the array going forward, not backward. – Edan Maor Nov 14 '09 at 11:00.

– Blindy Nov 14 '09 at 10:49 Pavel Shved wrote the correct answer. I just wrote a comment with some code. – sambowry Nov 14 '09 at 11:00 1 You should write comments into the question's "comment" field.

It also supports code blocks. – Johannes Schaub - litb Nov 14 '09 at 11:03 @litb: please copy my answer into a comment field of the question. Thank You.

– sambowry Nov 14 '09 at 12:41 1 There's no reason for a down vote. I find the answer to many questions on SO is "you shouldn't do that, do this instead". There is room for answers to the letter of the question and answer to the meaning of the question.

– jmucchiello Nov 14 '09 at 13:33.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions