I’ve run into an issue with our code under clang involving realloc. This code works fine under gcc and visual studio, so I’m interested in understanding clang’s behavior. Our code does something similar to this (error handling etc elided):
// allocate way more memory than we need
char * memory = malloc(500000);
int memoryused = 0;
// ... code goes here that fills up the memory, keeping track by
// setting memoryused ...
// now we're done, shrink the memory down to the size it needs
memory = realloc(memory, memoryused);
Under gcc and multiple versions of MSVC, the memory pointer wasn’t moved. However, under clang, it appears that it moves the memory, even if the size needed is only 1-2000 bytes.
Is there a particular reason that clang does this? The only one I can think of is that perhaps it keeps separate heaps for large and small allocations or something. Otherwise it seems a bit inefficient to move the memory around, when it could just truncate the old memory block and continue using it without having to copy the data at all.
I once wondered about this kind of thing as well: Is realloc guaranteed to be in-place when the buffer is shrinking?
To summarise the responses –
reallocis allowed to move the buffer around, even when it’s just shrinking… The exact details depend on your particular library implementation.From
c99(emphasis mine):As you’ve guessed at (and as per some responses in the linked question) some allocators apparently do partition the heap, so that allocations of a particular size range come from the same allocation bucket – preventing heap fragmentation in the case where lots of small objects might otherwise be strewn around, which would stop large contiguous blocks from being allocated.
Hope this helps.