3

In C/C++ when you want to dynamically allocate memory usually call malloc void* malloc (size_t size); which returns a pointer to a memory block of size bytes. Once you are done using this memory bloc, you call free() to free the memory back to the heap.

That's all fine, but what happens if you happen to call realloc void* realloc (void* ptr, size_t size); which changes the size of the memory block pointed by ptr. You still call free() when you are done using the memory, but my question is how does the compile know how much memory to free?

Intuitively I can come up with an answer, but I'm interested in implementation details - how is it really done? is it compiler dependent? it is part of a standard?

Thanks in advance!

Pandrei
  • 4,843
  • 3
  • 27
  • 44
  • 1
    In C you would use `malloc`, but in C++ you would not. – David Rodríguez - dribeas Dec 03 '13 at 23:13
  • I've seen it used in both c/c++; weather that is right or not is a different matter – Pandrei Dec 03 '13 at 23:17
  • 2
    short answer... it depends. There are many malloc/free algorithms, and some of them are optimized for various usage patterns. Also, the compiler doesn't know. These routines are implemented by libraries. – SirDarius Dec 03 '13 at 23:18
  • 1
    The answer that doesn't show up in the other question is, memory management is dynamic and not determined at compile-time. `malloc` and `free` (and `realloc`, `calloc`, and so on) are library functions which have their own data structures and track memory allocations dynamically. There isn't really a standard (though there are a few commonly used algorithms) because libraries can choose to implement memory management as they wish. – Michael Dec 03 '13 at 23:24

1 Answers1

3

To free memory, you don't generally need to say how much memory you want to free. The allocator already knows how much it gave you, and remembers that. The address of the allocated memory serves as a sort of "key" in the allocator's internal bookkeeping data structures. So all you need to do is give the address of the memory you want to free, and the allocator knows which memory you're talking about.

To be clear: there's no such thing as "partially freeing" some memory. You can't point into the middle of some allocated memory and say "free 100 bytes here". You release precisely what you acquired, no more and no less.

Finally, realloc is just a combination of malloc and memcpy, if you will, perhaps with a small optimization opportunity that allows an existing allocation to "grow" without moving the data. But the idea is the same.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I know how malloc/realloc/free work, I'm curios about how the compiler does the bookkeeping – Pandrei Dec 03 '13 at 23:18
  • The compiler doesn't do any bookkeeping. It's all in `libc` and dynamically tracked. – Michael Dec 03 '13 at 23:31
  • The operating system does the book keeping. The book 'Understanding the linux kernel' goes into some depth on how linux does this (although it's quite old now). – Will Dec 04 '13 at 10:54
  • @Will: The operating system usually does a much coarser level of bookkeeping. The allocator library will want to take large chunks of memory from the OS and handle the fine-grained user allocations itself. – Kerrek SB Dec 04 '13 at 11:38
  • It's perhaps worth mentioning what is big and small in this context? I.e. if you free a byte then it's going to be the allocator dealing with it. If you free 100k then the OS will deal with it. – Will Dec 04 '13 at 12:16
  • @Will: I think modern allocators *never* release memory to the OS. – Kerrek SB Dec 04 '13 at 14:24
  • @Kerrek SB I think I might not be understanding what you are saying here. If I malloc 100Megabytes in my program, then free it and keep running for ever, does the allocator hold on to it indefinitely? Can that be right? – Will Dec 04 '13 at 22:44
  • @Will: Sure, why not? – Kerrek SB Dec 04 '13 at 22:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42535/discussion-between-will-and-kerrek-sb) – Will Dec 04 '13 at 23:22
  • 1
    @Will: glibc malloc uses `mmap` for large allocations (above a tunable threshold, like 64k) so it definitely *can* hand them back to the kernel on `free`. This avoids keeping possibly large amounts of dirty anonymous pages in use if a program needs a lot of memory temporarily but then releases most of it and keeps running for a long time after. Letting them get swapped out to disk would make it *slower* to eventually reuse them (hard page fault) than if you had to ask the kernel for pages again later (usually a soft page fault from lazy allocation). – Peter Cordes Aug 20 '20 at 05:33