1

I suspect the answer to my question is language specific, so I'd like to know about C and C++. When I call free() on a buffer or use delete[], how does the program know how much memory to free?

Where is the size of the buffer or of the dynamically allocated array stored and why isn't it available to the programmer as well?

Puppy
  • 144,682
  • 38
  • 256
  • 465
Paul Manta
  • 30,618
  • 31
  • 128
  • 208
  • possible duplicate of [How do malloc() and free() work?](http://stackoverflow.com/questions/1119134/how-do-malloc-and-free-work) – S.Lott Sep 27 '11 at 23:15
  • There is nothing language specific about your question. – Puppy Sep 27 '11 at 23:15
  • possible duplicate of [C programming : How does free know how much to free?](http://stackoverflow.com/questions/1518711/c-programming-how-does-free-know-how-much-to-free) – Greg Hewgill Sep 27 '11 at 23:15
  • What part of this: http://en.wikipedia.org/wiki/Malloc was confusing or incomplete? It sure seems to describe all the details. What more do you want to know? – S.Lott Sep 27 '11 at 23:15

7 Answers7

2

Each implementation will be different, but typically the runtime allocates a bit more than asked for, and uses some hidden fields at the start of the block to remember the allocated size. The address returned to the caller is therefore offset a bit from the start of the memory claimed from the heap.

It isn't available to the caller because the true amount of memory claimed from the heap is an implementation detail, and will vary between compilers and platforms. As for knowing how much the caller asked for, rather than how much was allocated from the heap... well, the language designers assume that the programmer is capable of remembering this if needed.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • Which begs the question: if something like this was necessary, why doesn't the standard have some guidelines regarding the implementation so the programmer can also use the information? – Paul Manta Sep 27 '11 at 23:15
  • @Paul: Because the programmer _under no circumstances_ should use that information. The default `new/delete` and `malloc/free` are all provided by the standard library; you don't _have_ to use them. If you need your memory allocation to work a certain way, then you can call the OS functions to allocate pages of RAM and manage your heap manually. The Spec allows the default implementation to do whatever it wants, so as to better allow optimizations. For example, there are often small allocation optimizations that do things differently. – Nicol Bolas Sep 27 '11 at 23:21
1

The memory allocator that gave you that chunk of memory is responsible for all that maintenance data. Typically it's stored in the beginning of the chunk (right before the actual address you use) so it's easy to access on freeing.

Regarding to your other question: why should your app know about it? It's not your concern. It decouples memory allocation management from the app so you can use different allocators (for performance or debugging reasons).

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
1

The heap keeps track of all memory blocks, both allocated and free, specifically for that purpose. Typical (if naive) implemenation allocates memory, uses several bytes in the beginning for bookkeeping, and returns the address past those bytes. On subsequent operations (free/realloc), it would subtract a few bytes to get to the bookkeeping area.

Some heap implementations (say, Windows' GlobalAlloc()) let you know the block size given the starting address. But in the C/C++ RTL heap, no such service.

Note that the malloc() sometimes overallocates memory, so the information about mallocated block size would be of limited utility. C++ new[]'ed arrays, that's a whole another matter - for those, knowing exact array size is essential for array destruction to work properly. Still, there's no such thing in C++ as a dynamic_sizeof operator.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
0

It's stored internally in a location dependent on the language/compiler/OS.

Sometimes it is available (.Length in C# for example), though that may only refer to how much memory you're allowed to use, and not the object's total size.

Peter Drier
  • 1,327
  • 1
  • 11
  • 11
0

Usually because the size to free is stored somewhere within the allocated buffer. A common technique is to have the size stored in memory just previous to the returned pointer.

Why isn't such information available to the programmer? I don't really know. I guess its because an implementation may be able to provide memory allocation without actually needing to store its size, and such implementation -if it exists- shouldn't be penalized by the others.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
0

It's not so much language specific. It's all done by the memory manager.

How it knows depends on how the memory manager manages memory. The general idea is that the memory manager allocates more memory than you ask for. It stores extra data about the allocated blocks of memory in those locations. Thus, when you release the memory, it uses the information stored in those locations (reconstructed based on the given pointer) and figures out how much actual memory to stop managing.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
0

Don't confound deallocation and destruction.

free() knows the size of the memory because of some internal magic ("implementation-defined"), e.g. the allocator could keep a list of all the allocated memory regions indexed by their corresponding pointers and just look up the pointer to know what to deallocate; or that information could be stored next to the allocated memory itself in some hidden block of data.

The array-delete expression delete[] arr; does not only deallocate memory, but it also invokes all destructors. For that purpose, it is not sufficient to just know the memory size, but we also need to know the number of elements. For that purpose, new T[N] actually allocates more than sizeof(T) * N bytes of memory, so the array-deleter knows how many destructors to call. All that memory is properly deallocated by the corresponding delete-operator.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I know the difference between `free` and `delete[]` -- it's also irrelevant to my question. – Paul Manta Sep 27 '11 at 23:21
  • Well, the two have very different answers concerning your question about "the size of the array": `free()` has no idea, and `delete[]` does. – Kerrek SB Sep 27 '11 at 23:23