我有一个非常大的,分散的类,基本上是一个非常人为的二维链表。我希望能够“编译”它,我的意思是我想最终确定列表,这样只能进行读访问,然后将所有元素移动到连续的内存空间。我的粗略解决方案是:
#include <new>
...
MyListNode* pool = new MyListNode[length];
new(&pool[position]) MyListNode();
问题是我基本上有两个类,一个用new分配,另一个用这个方法分配,当我尝试删除上面方法分配的任何对象时,glibc因为指针无效。
自然的解决方案是创建两个类,并且只使用运行时多态来提供一个接口但只有两个实现,等等。有什么方法可以让C ++中的内存标准允许这种jiggery pokery?
答案 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);