Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C中的“free”不接受要释放的字节数?_C_Memory Management_Malloc_Free - Fatal编程技术网

为什么C中的“free”不接受要释放的字节数?

为什么C中的“free”不接受要释放的字节数?,c,memory-management,malloc,free,C,Memory Management,Malloc,Free,需要明确的是:我确实知道malloc和free是在C库中实现的,C库通常从操作系统分配内存块,并自行管理将少量内存分配给应用程序,并跟踪分配的字节数。这个问题不是 相反,我想知道为什么free一开始就是这样做的。作为一种低级语言,我认为要求C程序员不仅要跟踪分配了什么内存,还要跟踪分配了多少内存是完全合理的(事实上,我通常发现我最终还是要跟踪malloced的字节数)。我还想到,显式地给空闲提供字节数可能会允许一些性能优化,例如,对于不同的分配大小,具有单独池的分配器将能够通过查看输入参数来确定

需要明确的是:我确实知道
malloc
free
是在C库中实现的,C库通常从操作系统分配内存块,并自行管理将少量内存分配给应用程序,并跟踪分配的字节数。这个问题不是

相反,我想知道为什么
free
一开始就是这样做的。作为一种低级语言,我认为要求C程序员不仅要跟踪分配了什么内存,还要跟踪分配了多少内存是完全合理的(事实上,我通常发现我最终还是要跟踪malloced的字节数)。我还想到,显式地给
空闲
提供字节数可能会允许一些性能优化,例如,对于不同的分配大小,具有单独池的分配器将能够通过查看输入参数来确定要从哪个池中释放,并且总体上空间开销将更小

那么,简而言之,为什么要创建
malloc
free
,以便要求它们在内部跟踪分配的字节数?这只是一个历史性的意外吗

小编辑: 一些人提供了类似“如果你的免费金额与你分配的金额不同怎么办”这样的观点。我想象中的API可能只需要释放所分配的字节数;或多或少的释放可以简单地由UB或实现定义。我不想阻止其他的可能性的讨论。

C可能不是“抽象”的C++,但它仍然是一个抽象的集合。为此,从等式中去掉了最低级别的细节。这在很大程度上防止了你不得不偷偷摸摸地进行对齐和填充,这会使你所有的C程序都不可移植


简而言之,这就是编写抽象的全部要点。

malloc和free-go齐头并进,每个“malloc”对应一个“free”。因此,完全有意义的是,匹配先前“malloc”的“free”应该只是释放该malloc分配的内存量——这是在99%的情况下有意义的大多数用例。想象一下,如果世界各地的所有程序员都使用malloc/free,那么所有的内存错误都需要程序员跟踪malloc中分配的数量,然后记住释放相同的内存。您所讨论的场景实际上应该是在某种内存管理实现中使用多个malloc/free。

我建议这样做是因为不必以这种方式手动跟踪大小信息(在某些情况下)非常方便,而且程序员也不太容易出错

此外,realloc需要这个簿记信息,我希望它包含的不仅仅是分配大小。i、 e.它允许定义其工作的机制


<>你可以编写你自己的分配器,它按你建议的方式工作,而且它经常在C++中以类似的方式在特定情况下(以潜在的巨大性能增益)为池分配器完成。虽然这通常是根据分配池块的新操作员来实现的。

我只是将此作为一个答案发布,不是因为这是您希望的答案,而是因为我相信这是唯一似乎正确的答案:

它最初可能被认为是方便的,此后再也无法改进。
很可能没有令人信服的理由。(但如果显示它不正确,我很乐意删除它。)

如果可能的话,会有一些好处:您可以分配一个事先知道大小的大块内存,然后一次释放一点,而不是重复分配和释放小块内存。目前这样的任务是不可能的


对于你们中的许多人(很多!),他们认为通过这个尺寸是非常可笑的: 我可以让您参考C++关于该方法的设计决策吗? 在调用之前,应销毁
p
所指区域中的所有
n
T
对象。
n
应匹配传递给
分配的值,以获得该内存。

我认为你将有一个相当“有趣”的时间来分析这个设计决策


至于
运营商删除
,2013年的提案(“C++规模的解除分配”)也旨在解决这一问题。
1只需查看原始问题下的评论,就可以了解有多少人草率断言,例如“所要求的尺寸对于
免费
呼叫完全没有用处”,以证明缺少
尺寸
参数是合理的

“为什么C中的
free
不获取要释放的字节数?”

因为没有必要这样做,而且也没有什么意义

当您分配某些内容时,您希望告诉系统要分配多少字节(出于明显的原因)

但是,当您已经分配了对象时,您得到的内存区域的大小现在已经确定。这是含蓄的。它是一个连续的内存块。你不能取消分配它的一部分(让我们忘记
realloc()
,反正这不是它正在做的),你只能取消分配整个东西。你也不能“取消分配X字节”——你要么从
malloc()
释放内存块,要么不释放

现在,如果您想释放它,您可以告诉内存管理器系统:“这是指针,
free()
它所指向的块。”-内存管理器将知道如何做,因为它隐式地知道大小,或者因为它甚至不需要大小。

例如,
malloc()
mai的大多数典型实现
void deallocate(pointer p, size_type n);
void * p = malloc(20);
free(p, 25); // (1) wrong size provided by client code
free(NULL, 10); // (2) generic argument mismatch
void *my_alloc(size_t size) {
    void *block = malloc(sizeof(size) + size);
    *(size_t *)block = size;
    return (void *) ((size_t *)block + 1);
}
void my_free(void *block) {
    block = (size_t *)block - 1;
    mfree(block, *(size_t *)block);
}