4

Possible Duplicate:
How do free and malloc work in C?

How does free know how many bytes of memory to be free'd when called in a program?

Community
  • 1
  • 1
Pradeep Nayak
  • 675
  • 1
  • 10
  • 24
  • 5
    Was going to answer, but this is a duplicate of: http://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c The top voted answers describe how the allocators/memory managers could work to keep track of allocated memory. – wkl Feb 25 '11 at 18:52

5 Answers5

8

This is implementation specific, but when malloc is called, the size of the allocated memory is kept somewhere (usually offset from the pointer itself). When free is called, it will use that stored size.

This is exactly why you should only ever call free on a pointer that was returned by malloc.

Kevin
  • 1,889
  • 14
  • 11
  • I believe the typical layout of a block of allocated memory is `[metadata|memory-the-user-requested]`. The metadata (12 bytes or so) includes the length of the entire block. And the pointer returned by `malloc()` points at the first byte of the user memory region, so you don't really know that the metadata is there. – Xavier Holt Feb 25 '11 at 18:58
  • 2
    This depends entierly on the implementation, there's malloc implementation that does not store the size within the memory block allocated, but rather uses the pointer value as an index key into an internal datastructure where metadata such as the size is stored – nos Feb 25 '11 at 19:57
3

It's done automatically. The corresponding "malloc" has saved the size in a secret place (typically stored at a negative offset from the pointer).

This, of course, mean that you can only free memory that corresponds to a block previously allocated by "malloc".

Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • Secret place?? This is unique, never knew that. But isn't free called with a pointer to which malloc allocated the memory to? – Pradeep Nayak Feb 25 '11 at 18:58
  • @Pradeep: Did you miss the part about "typically stored at a negative offset from the pointer"? – Fred Larson Feb 25 '11 at 19:01
  • @Fred: My understanding was whenever malloc allocated memory it allocates randomly from the heap and not necessarily these locations are not next to each other. So I thought free returns the dynamically allocated memory to the heap. I thought it is paired with every malloc() call – Pradeep Nayak Feb 25 '11 at 19:43
  • @Pradeep: `malloc()` returns a pointer to someplace within the buffer it allocates, not necessarily the beginning of that buffer. It may store the size before that pointer (hence, "at a negative offset from the pointer"). So `free()` just has to do a little pointer arithmetic to get that size as well as return the pointer to the actual beginning of the buffer. – Fred Larson Feb 25 '11 at 19:50
2

Asking how it knows "how many bytes to free" is a mistake. It's not like each byte individually has a free/not-free status bit attached to it (well, it could, but this would be an awful implementation). In many implementations the number of bytes in an allocation may be completely irrelevant; it's the data structures used to manage it that are relevant.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
1

It's an implementation detail than can and will vary between different platforms. Here's one example though of how it could be implemented.

Every free call must be paired with a malloc / realloc call which knows the size request. The implementation of malloc could choose to store this size at an offset of the returned memory. Say by allocating a larger buffer than requested, stuffing the size in the front and then returning an offset into the allocated memory. The free function could then simply use the offset of the provided pointer to discover the size to free.

For example

void* malloc(size_t size) {
  size_t actualSize = size + sizeof(size_t);
  void* buffer = _internal_allocate(actualSize);
  *((size_t*)buffer) = size;
  return ((size_t*)buffer) + 1;
}

void free(void* buffer) {
  size_t* other = buffer;
  other--;
  size_t originalSize = *other; 
  // Rest of free
  ...
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
0

The answer is implementation-specific.

  • malloc might keep a dictionary mapping addresses to data records
  • malloc might allocate a slightly larger block than requested and store metadata before or after the block it actually returns.
  • In some special cases, not intended for general use, free() is completely a no-op and it doesn't actually keep track.
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329