释放动态分配块的部分?

时间:2012-03-01 07:47:51

标签: c malloc dynamic-allocation

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

例如:

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) 

为什么这是明智/不明智/困难的想法?怎么做?

对我来说似乎很有用。

谢谢!

=====编辑===== 经过一些研究,似乎linux内核的bootmem分配器允许类似于bootmem_free调用的此操作。所以,我很好奇 - 为什么bootmem分配器允许这样,但ANSI C没有?

3 个答案:

答案 0 :(得分:3)

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

来自c标准:

7.22.3.5 realloc功能

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

realloc函数释放ptr指向的旧对象,并返回指向大小指定大小的新对象的指针。新对象的内容应与解除分配之前的旧对象的内容相同,直到新旧大小中的较小者为止。新对象中超出旧对象大小的任何字节都有不确定的值。

答案 1 :(得分: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 s原始分配的内存。

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

答案 2 :(得分:1)

首先,我无法想到你可能需要这样的事情(当存在realloc以增加/减少答案中提到的内存时)。

我想补充一点。在我看到的malloc子系统的任何实现中(我承认不是很多),malloc和free被实现为依赖于称为前缀字节的东西。因此,无论malloc返回给您什么地址,malloc子系统都会在返回给您的地址之前分配一些额外的内存字节,以存储包含已分配字节数和可能的分配策略的完整性检查信息。 (如果你的操作系统支持多个内存分配策略)等等。当你说像free(x字节)这样的东西时,malloc子系统会回过头来回寻前缀字节以进行健全性检查,只有当它找到前缀时才会自由成功发生。因此,它不允许你从中间开始释放一些块。