gowrath
gowrath

Reputation: 3224

Does realloc() free old memory (when old memory might be pointers to other memory)?

Suppose I have a pointer p1 to an array (on the heap) of structs s1 where each struct s1 also has a pointer to another struct s2 (on the heap). If I call realloc() on p1 to resize it, will the old memory being held by the structs of the pre-realloced array be freed (the s2s on the heap)?

I'm fairly sure the answer to this question is no because the documentation states that if the area pointed to was moved, a free(ptr) is done which implies that it will only free up to one level deep. Is that correct? And if so, would the best solution be to manually malloc a new array, iterate over the old array, copy the values to the new larger array, and free the structs while at it?

Upvotes: 2

Views: 9438

Answers (3)

Peter Skarpetis
Peter Skarpetis

Reputation: 553

The answer is definitely no. Realloc works is as follows:

realloc will either use the existing pointer or allocate a new pointer if the old one cannot be shrunk or expanded in place. If a new pointer is allocated, the contents of the old memory, as much as would fit at the new location, are copied.

In your case, if realloc shrinks the memory block then all the s1 pointers in the new block are valid, however the s1 pointers the are beyond the new block of memory would cause a memory leak as neither the s1 pointers nor the s2 pointers were freed. To avoid the memory leak you should free the memory they point to, before calling realloc.

Another thing to be aware of with realloc is that if it returns null, then the old memory pointer is still valid, so you should keep a copy of it and either reuse or free it on failure.

Upvotes: 3

Barmar
Barmar

Reputation: 782693

realloc() only reallocates the top-level array you give it. As EOF mentioned in a comment, it doesn't know that the contents of the array are pointers, so it can't do anything to those elements.

If you're enlarging the array, you don't need to do anything with the arrays that it points to. Their memory is untouched, and the pointers will be copied from the old memory to the new memory allocated by realloc().

If you're shrinking the array, you need to make sure that you first free any of the arrays that were pointed to by the elements that are beyond the end of the result, to avoid leaking memory.

Upvotes: 4

Paul92
Paul92

Reputation: 9082

No, realloc MAY do a level 1 free, but not more. It will not free the pointers inside your structs. I said it may do the free since if the array can grow and not be moved, it will simply grow in the same place.

The alternative solution you suggest is kind of what realloc is doing behind the scenes (assuming we're still talking about enlarging the array and not some other struct operations), and it's usually a bad idea to reimplement a thing from a standard library unless you have a good reason to (and you don't seem to have).

Upvotes: 3

Related Questions