1

我很好奇是否存在允许程序员释放部分已分配块的动态内存分配系统。

例如:

char* a = malloc (40);
//b points to the split second half of the block, or to NULL if it's beyond the end
//a points to a area of 10 bytes
b = partial_free (a+10, /*size*/ 10) 

关于为什么这是明智/不明智/困难的想法?这样做的方法?

在我看来,它可能很有用。

谢谢!

=====edit===== 经过一番研究,似乎 linux 内核的 bootmem 分配器允许与 bootmem_free 调用类似的操作。所以,我很好奇——为什么 bootmem 分配器允许这样做,但 ANSI C 不允许?

4

3 回答 3

3

不,没有这样的功能可以部分释放内存。
但是,您可以使用realloc()来调整内存大小。

从c标准:

7.22.3.5realloc功能

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

realloc 函数释放 ptr 指向的旧对象,并返回一个指向具有 size 指定大小的新对象的指针。新对象的内容应与释放前旧对象的内容相同,直至新旧大小中的较小者。新对象中超出旧对象大小的任何字节都具有不确定的值。

于 2012-03-01T07:48:40.033 回答
1

首先,我想不出您可能需要这种东西的任何情况(当存在 realloc 来增加/减少答案中提到的内存时)。

我想补充一点。在我看到的 malloc 子系统(我承认不是很多)的任何实现中,malloc 和 free 都被实现为依赖于称为前缀字节的东西。因此,无论 malloc 返回给您的地址是什么,malloc 子系统在内部都会在返回给您的地址之前分配一些额外的内存字节,以存储完整性检查信息,其中包括分配的字节数以及您使用的可能的分配策略(如果您的操作系统支持多个内存分配策略)等。当您说诸如免费(x 字节)之类的内容时,malloc 子系统会返回以查看前缀字节以进行完整性检查,并且只有在找到适当的前缀时才会释放免费顺利发生。因此,它不允许您从中间开始释放一些块。

于 2012-03-01T10:20:15.373 回答
1

没有现成的功能,但这样做并非不可能。首先,有realloc()realloc获取一个指向内存块的指针并将分配的大小调整为指定的大小。

现在,如果您分配了一些内存:

char * tmp = malloc(2048); 

并且您打算释放第一个 1 K 的内存,您可以这样做:

tmp = realloc(foo, 2048-1024);

但是,这种情况下的问题是您不能确定tmp会保持不变。因为,该函数可能只是释放整个 2K 内存并将其移动到其他地方。

现在我不确定realloc的确切实现,但据我了解,代码:

myptr = malloc( x - y );

实际上malloc是一个大小的新内存缓冲区x-y,然后它复制适合使用的字节,memcpy最后free是原始分配的内存。

这可能会产生一些潜在的问题。例如,新重新分配的内存可能位于不同的地址,因此您可能拥有的任何过去的指针都可能变得无效。导致未定义的运行时错误、分段错误和一般调试地狱。所以我会尽量避免诉诸于此。

于 2012-03-01T08:17:06.847 回答