If free() knows the length of my array, why can't I ask for it in my own code?

I know that it's a common convention to pass the length of dynamically allocated arrays to functions that manipulate them:

void initializeAndFree(int* anArray, size_t length);

int main(){
    size_t arrayLength = 0;
    scanf("%d", &arrayLength);
    int* myArray = (int*)malloc(sizeof(int)*arrayLength);

    initializeAndFree(myArray, arrayLength);
}

void initializeAndFree(int* anArray, size_t length){
    int i = 0;
    for (i = 0; i < length; i++) {
        anArray[i] = 0;
    }
    free(anArray);
}

but if there's no way for me to get the length of the allocated memory from a pointer, how does free() "automagically" know what to deallocate when all I'm giving it is the very same pointer? Why can't I get in on the magic, as a C programmer?

Where does free() get its free (har-har) knowledge from?


Besides Klatchko's correct point that the standard does not provide for it, real malloc/free implementations often allocate more space then you ask for. Eg if you ask for 12 bytes it may provide 16 (see A Memory Allocator, which notes that 16 is a common size). So it doesn't need to know you asked for 12 bytes, just that it gave you a 16-byte chunk.


You can't get it because the C committee did not require that in the standard.

If you are willing to write some non-portable code, you may have luck with:

*((size_t *)ptr - 1)

or maybe:

*((size_t *)ptr - 2)

But whether that works will depend on exactly where the implementation of malloc you are using stores that data.


While it is possible to get the meta-data that the memory allocator places preceding the allocated block, this would only work if the pointer is truly a pointer to a dynamically allocated block. This would seriously affect the utility of function requiring that all passed arguments were pointers to such blocks rather than say a simple auto or static array.

The point is there is no portable way from inspection of the pointer to know what type of memory it points to. So while it is an interesting idea, it is not a particularly safe proposition.

A method that is safe and portable would be to reserve the first word of the allocation to hold the length. GCC (and perhaps some other compilers) supports a non-portable method of implementing this using a structure with a zero length array which simplifies the code somewhat compared to a portable solution:

typedef tSizedAlloc
{
    size_t length ;
    char* alloc[0] ;   // Compiler specific extension!!!
} ;

// Allocating a sized block
tSizedAlloc* blk = malloc( sizeof(tSizedAlloc) + length ) ;
blk->length = length ;

// Accessing the size and data information of the block
size_t blk_length = blk->length ;
char*  data = blk->alloc ;
链接地址: http://www.djcxy.com/p/86494.html

上一篇: 在c ++中可以动态分配的最大内存和编译时间

下一篇: 如果free()知道我的数组的长度,为什么我不能在自己的代码中请求它?