【问题标题】:Freeing only a portion of memory allocated with "operator new"仅释放使用“operator new”分配的一部分内存
【发布时间】:2015-03-05 18:12:15
【问题描述】:

理论上,如果内存中的空间是使用operator new 分配的,是否有可能以零碎的方式释放该内存?例如,如果使用void *mem = operator new(sizeof(int)*2) 将内存地址分配给两个int* 变量,一个在mem,另一个在mem+sizeof(int),是否可以释放其中一个的内存,但不能释放另一个?

据我了解operator new只分配内存,不调用任何构造函数,所以使用放置new在内存中精确空间调用构造函数。如果这些分配的内存地址是已知的,但在内存中不一定是线性的(例如,存储在内存池类的链表中),我想会有一种适当的方法来释放分配的内存遍历内存地址的链表并释放分配大小的内存。但是,通过将内存分配给指向适当大小的数据类型的指针,总是会引发运行时错误。

有合适的方法吗?

理论例子:

// This works fine
uintptr_t mem1 = reinterpret_cast<uintptr_t>(operator new(sizeof(int)));
int *a = new(reinterpret_cast<void*>(mem1)) int(1);
printf("a|*a\t\t%p|%d\n", a, *a);
delete a;

// Both of the pointers can be assigned to the appropriate positions...
uintptr_t mem2 = reinterpret_cast<uintptr_t>(operator new(sizeof(int) * 2));
int *b = new(reinterpret_cast<void*>(mem2)) int(2);
printf("b|*b\t\t%p|%d\n", b, *b);
int *c = new(reinterpret_cast<void*>(mem2+sizeof(int))) int(3);
printf("c|*c\t\t%p|%d\n", c, *c);

// ...but attempting to delete them results in a runtime error.
operator delete(b);
operator delete(c);
//using "operator delete(reinterpret_cast<void*>(mem2));" works just fine, but I'm operating on the assumption that the addresses may be non-linear, in a linked-list of addresses of a constant size

【问题讨论】:

  • @0x499602D2 分配,我的错。
  • 不,这是不可能的。我想你可以制作一个自定义的分配器和释放器,但是为什么无缘无故地让你的生活复杂化呢?
  • @bolov 因为我决心完成这项工作。

标签: c++ memory memory-management memory-leaks


【解决方案1】:

18.6.1.1/12 (void operator delete(void* ptr) noexcept):

要求:ptr 应为空指针,或其值应为先前调用(可能被替换的)operator new(std::size_t) 或 operator new(std::size_t,const std::nothrow_t&amp;) 所返回的值,该调用尚未因对 @ 的介入调用而无效987654325@.

我认为关于分段销毁分配的内存,我认为没有比这更明确的了:标准不允许这样做。

【讨论】:

    【解决方案2】:

    如果您的意思是“新操作符可以分配一大块内存,然后将其中的一部分返回给调用者,从而使内存分配真正有效”,那么一般来说,是的......这已经发生了。在现代系统中,您甚至没有分配任何内存 - 发生的情况是您分配了一块虚拟地址空间,只有在您写入时才由真实内存支持,CPU MMU 为您处理所有这些。

    不支持的是在应用程序代码级别分配内存并尝试部分释放它,您从 new 中获得的内容是您必须作为单个块使用的内容。

    【讨论】:

      猜你喜欢
      • 2023-01-21
      • 1970-01-01
      • 2020-11-09
      • 2021-05-20
      • 1970-01-01
      • 2017-01-31
      • 2014-01-23
      • 1970-01-01
      • 2011-12-09
      相关资源
      最近更新 更多