【问题标题】:Freeing portions of dynamically allocated blocks?释放部分动态分配的块?
【发布时间】:2012-03-01 07:47:51
【问题描述】:

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

例如:

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 不允许?

【问题讨论】:

  • realloc,基本上可以做你想做的事。

标签: c malloc dynamic-allocation


【解决方案1】:

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

来自c标准:

7.22.3.5 realloc 函数

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

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

【讨论】:

  • 对,但是realloc 不允许在块中间释放内存,同时在部分释放部分后保持内存内容,对吗?
  • @bcr:不,它没有,因此答案是,
  • 我可以知道否决这个的原因吗?
【解决方案2】:

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

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

char * tmp = malloc(2048); 

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

tmp = realloc(foo, 2048-1024);

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

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

myptr = malloc( x - y );

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-03-17
      • 2015-10-14
      • 2013-11-22
      • 2012-01-08
      • 2013-04-14
      • 2019-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多