4

I have a sort of theoretical question about freeing a pointer.

I think some guy (the program itself, or OS) have to keep track of the pointers and the length of them. Why?

float* pointer1 = malloc( 100 * sizeof(float) );

For example: I have a float pointer here. Can somebody tell me what is the length of my pointer1 array? There is no way to get the length of that pointer with calling a function/method at run-time right? So how the program (or the OS) is able to free that memory part of the pointer without knowing the real length of it at run-time:

free(pointer1);

If the program knew the length of the pointer to free, why we are not able to get that information and using some other ways to keep track of the lengths. For example:

struct floatArray
{
    float* pointer;
    int length;
}

So, I am really curious about this issue. I really want to learn how the OS take cares of the pointers lenghts.

Thanks,

Sait.

Sait
  • 19,045
  • 18
  • 72
  • 99
  • There is no such thing as "freeing a pointer". You free *objects* obtained by malloc. A pointer to that object is how you reference it for the purpose of freeing it, but you're not freeing the pointer; you're freeing the object. – R.. GitHub STOP HELPING ICE May 05 '12 at 21:04
  • @R.. Yes, you are right. I should have said: "Free an object stored on the memory with using a pointer". +1. – Sait May 05 '12 at 21:17

4 Answers4

4

The memory manager does indeed maintain metadata about each allocated block of memory. This will likely contain information in addition to the size of the block.

One common way to implement this is to store the metadata in memory just below the memory address which the user program uses to refer to the block. So if the call to malloc returns address p, and the meta data contains n bytes, then the meta data will be stored in addresses p-n to p-1.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • So why there is not a global function to get the length of any pointer? Something like: int GetLength(void* pointer). Wouldn't it be useful? – Sait May 05 '12 at 20:53
  • 1
    @zagy It would be useful. But the C designers chose not to constrain implementors in that way. Many implementations include such a function as an implementation specific extension. – David Heffernan May 05 '12 at 20:54
2

It is usually not directly the OS, it is the malloc() implementation - the memory manager, which gets larger blocks of memory from the OS. Usually, this information will be stored in some linked-list but I suggest you look at your libc's malloc() to see how this information is really stored.

As pointed out, there is not a standard way to do it, because the implementation varies between different compilers/standard C libraries-

1

It is not necessarily the case that the OS tracks the exact length that you requested. Often the length is altered (increased) for various internal reasons, or stored in a way that is slow to access. It may have additional information encoded in it (typically the size is aligned to some multiple of a power of two and the low bits used as flags). Some malloc implementations (particularly embedded ones) simply don't implement free() at all, and have no need to store this information.

The C language designers wanted to allow this kind of freedom to the C library implementation, and so they don't allow the program to retrieve the size of a malloc'd buffer.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • What if nobody keeps track of the used memory space, how it is possible to give somebody an empty memory space? It doesn't make sense to me. The platforms that we use had to be more unstable in that case, I think. – Sait May 05 '12 at 21:04
  • @zagy, nope, you just set up an empty heap at boot, set a pointer to the start, and add to it when someone mallocs. Eventually you run out of memory and have to reboot. You generally only see this in embedded systems where there'll be a bunch of mallocs at boot, and then it'll never malloc again. The Linux kernel boot decompressor also does this; once it's done decompressing the real kernel its heap is entirely erased. – bdonlan May 05 '12 at 22:14
1

With MSVC or MinGW you can use the (non-standard!) function _msize

float* pointer1 = malloc( 100 * sizeof(float) );
printf("%lu bytes with %lu elements", (unsigned long)_msize(pointer1),(unsigned long)_msize(pointer1)/sizeof*pointer1);
user411313
  • 3,930
  • 19
  • 16
  • Interesting... I really didn't know there exists such a function. Thanks. And I'm sad to hear that it's non-standard. – Sait May 05 '12 at 21:10