我正在做一些新的放置时髦的东西,而且事情都失败了。解决方法?

时间:2010-07-18 16:21:44

标签: c++ memory new-operator

我有一个非常大的,分散的类,基本上是一个非常人为的二维链表。我希望能够“编译”它,我的意思是我想最终确定列表,这样只能进行读访问,然后将所有元素移动到连续的内存空间。我的粗略解决方案是:

#include <new>
...
MyListNode* pool = new MyListNode[length];
new(&pool[position]) MyListNode();

问题是我基本上有两个类,一个用new分配,另一个用这个方法分配,当我尝试删除上面方法分配的任何对象时,glibc因为指针无效。

自然的解决方案是创建两个类,并且只使用运行时多态来提供一个接口但只有两个实现,等等。有什么方法可以让C ++中的内存标准允许这种jiggery pokery?

2 个答案:

答案 0 :(得分:3)

显而易见的可能性是检查对象的地址,只有在不在池外时才删除它。如果我这样做,我想我可能会为该类重载operator new,并且总是从池中分配空间。这样你就可以在没有复制的情况下获得连续的分配,并且你的对象被统一分配,所以你也可以统一删除它们。

答案 1 :(得分:2)

您是否在阵列中的某个对象上调用了delete?或者您是否手动调用析构函数来镜像新的位置?

由于您只有一次对非展示位置的调用,因此您应该只有一次要删除的调用。而且由于您对placement-new进行了n次调用,因此您应该手动调用析构函数n次。

所以,你可能想要这样的东西:

// Allocate an array of chars instead of an array of MyListNode.  Since we
// are going to use placement new, this is necessary if MyListNode has a
// a default constructor
MyListNode* pool = static_cast<MyListNode *>(new char[sizeof(MyListNode) * length);
for (size_t position = 0; position < length; ++position)
    new(&pool[position]) MyListNode();

...

for (position = 0; position < length; ++position)
    pool[position].~MyListNode()

delete[] static_cast<char *>(pool);