检测堆栈或堆分配

我有一个班,我希望能够设置一个标志,说如果它是堆分配,所以它可以适当清理后,而不是尝试删除自己,如果它在堆栈上。 问题是......我似乎无法同时重写new和构造函数。 所以它从我的new重载设置isHeapAllocated标志,然后到我的构造函数重置标志。

void* String8::operator new(size_t size)
{
    String8* string = (String8*)malloc(size);
    if(string == null)
        Exception("allocation fail : no free memory");
    string->isHeapAllocated = true;
    return string;
}

String8::String8() 
{
    isHeapAllocated = false;
}

所以new String8()设置isHeapAllocated标志,然后将其重置为false 。 有没有办法做到这一点?


它不会按预期工作:

新的运算符返回单元化内存给予构造函数。 你 - 正确地做String8* string = (String8*)malloc(size); ,但是*string ,在这个阶段还不是一个String8对象:它只是包含它的内存批量。

所以string->isHeapAllocated = true; 实际上在一个尚未构造的对象(即UB)内设置一个标志。

承认这一点不会影响操作系统的进程,所以程序不会崩溃(你写的内存已经属于你了,毕竟...),当你稍后再做一些像String8* ptr = new String8; ,在新的返回之后,String8 :: String8构造函数被调用,并且成员将独立于您在新运算符重载中执行的操作而重新设置为“false”。

管理C ++对象的惯用方式是由谁来分配负责解除分配。 (如果“谁”是堆栈,它只是按照定义来做)。


这是一个坏主意,但是这里有一种方法可以实现,它不会引发未定义的行为。

#include <iostream>
#include <memory>
#include <set>

using namespace std;

class C {
public:

  void* operator new(size_t size) {
    C* c = static_cast<C*>(::operator new(size));
    heap_instances.insert(c);
    return c;
  }

  C() : heap_allocated(heap_instances.find(this) != heap_instances.end()) {}

  const bool heap_allocated;

private:
  static set<const C*> heap_instances;
};

set<const C*> C::heap_instances;

int main(int argc, char** argv) {
  cout << boolalpha;

  C stack;
  cout << stack.heap_allocated << 'n'; // false

  C* heap_nozero = new C;
  cout << heap_nozero->heap_allocated << 'n'; // true
  delete heap_nozero;

  C* heap_zero = new C();
  cout << heap_zero->heap_allocated << 'n'; // true
  delete heap_zero;
}

当你完成这些操作时,你可以从heap_instances移除指针,如果你在多线程环境中运行,可以使用更适合的容器。 但是,我不会建议你真的这样做 - 基于分配的决定行为不是一个对象应该做的事情。

我能想到的唯一正当理由是为了delete this 。 尽管在对象自杀后小心不要访问成员是安全的,但让对象管理其他对象的生命周期通常更为安全。


请注意,如果构造器分配在堆栈或堆上,并且没有办法让对象检测它是在堆栈还是堆中分配的。

要在堆栈中创建一个对象,不要使用像这样的任何内存分配函数

String8 myString;

在堆上创建它

String8 *myString = new String8();

请注意,不必再使用对象后,您必须手动进行清理。

对于绑定到堆栈范围的堆对象的使用,您可以查看由c ++程序强烈使用的RAII原则(请参阅此处以更好地解释堆分配和堆栈分配的差异)。

链接地址: http://www.djcxy.com/p/96545.html

上一篇: Detecting stack or heap allocation

下一篇: Managing Scope and Object Lifetime Within STL Vectors