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

我知道将动态分配数组的长度传递给操作它们的函数是一个常见惯例:

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);
}

但如果没有办法让我从指针中获取分配内存的长度,那么free()自动“知道当我给它的所有内容都是同一个指针时要释放的内容? 为什么我不能像C程序员那样获得魔术?

free()从哪里获得免费(har-har)知识?


除了Klatchko的标准没有提供的正确观点之外,真正的malloc / free实现通常会分配更多的空间,然后请求。 例如,如果你询问12个字节,它可能会提供16个字节(请参阅内存分配器,它指出16是常见大小)。 所以它不需要知道你问了12个字节,只是它给了你一个16字节的块。


你不能得到它,因为C委员会在标准中没有要求。

如果你愿意编写一些不可移植的代码,你可能会遇到以下问题:

*((size_t *)ptr - 1)

或者可能:

*((size_t *)ptr - 2)

但是,这是否会起作用将取决于您正在使用的malloc的实现在哪里存储数据。


虽然有可能获得内存分配器放置在分配块之前的元数据,但只有当指针确实是指向动态分配块的指针时才会起作用。 这会严重影响函数的实用性,要求所有传递的参数都是指向这些块的指针,而不是说简单的自动或静态数组。

关键是从检查指针的角度来看,没有可移植的方式来知道它指向的内存类型。 所以虽然这是一个有趣的想法,但这不是一个特别安全的提议。

一种安全和便携的方法是保留分配的第一个字来保存长度。 GCC(以及其他一些编译器)支持一种不可移植的方法来实现这一点,它使用一个长度为零的结构,与便携式解决方案相比,它简化了代码:

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/86493.html

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

下一篇: Malloc Memory Questions