tags:

views:

279

answers:

5

I am wondering whether the C or C++ standard guarantees that a pointer is not changed when realloc is called with a smaller (nonzero) size:

size_t n=1000;
T*ptr=(T*)malloc(n*sizeof(T));
//<--do something useful (that won't touch/reallocate ptr of course)
size_t n2=100;//or any value in [1,n-1]
T*ptr2=(T*)realloc(ptr,n2*sizeof(T));
//<-- are we guaranteed that ptr2==ptr ?

Basically, can the OS decide on its own that since we freed a large memory block, he wants to take advantage of all reallocs to defragment the memory, and somehow move ptr2 ?

+1  A: 

With realloc, you get absolutely no guarantees about where the memory will live afterwords. I believe that libc's default malloc will only begrudgingly copy memory around, so practically speaking you may be OK. But don't count on it.

zenazn
+8  A: 

http://opengroup.org/onlinepubs/007908775/xsh/realloc.html

Upon successful completion with a size not equal to 0, realloc() returns a pointer to the (possibly moved) allocated space.

Nope, no guarantee

Jeffrey Aylesworth
Earlier on that page, it says "The realloc() function changes the size of the memory object pointed to by ptr to the size specified by size. The contents of the object will remain unchanged up to the lesser of the new and old sizes. If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed." It doesn't rule out motion, but it is relatively unlikely.
Jonathan Leffler
Yes, you are still guaranteed that whatever was in memory before would still be there, thanks for pointing that out
Jeffrey Aylesworth
A: 

On Windows, the C-Runtime grabs a heap, and then allocates memory from that heap. So the OS won't know about individual memory allocations, and thus won't move things around.

DougN
This is not correct. The Visual C run-time does not directly call the OS heap implementation, for one thing. For another, the HeapReAlloc() call _does_ move things around.
Heath Hunnicutt
You need to double check your docs. See:http://msdn.microsoft.com/en-us/library/csd157zx.aspxThe CRT grabs a single OS heap to use internally. It then sub-allocates that heap (meaning it doesn't use the Win32 heap calls to do allocations within that heap)
DougN
+3  A: 

There's no guarantee realloc will return the same location, period.

Jim Zajkowski
A: 

realloc is not required to leave the block in place even if it would fit, and in fact the simplest stub implementation is an example where it might not:

  • malloc: call sbrk.
  • realloc: call malloc and memcpy.
  • free: no-op.

This may sound ridiculous, but sometimes for embedded systems an implementation like I've just described is actually the optimal one.

R..