Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ I';我用新的布局做一些时髦的事情,但事情正在失败。变通办法?_C++_Memory_New Operator - Fatal编程技术网

C++ I';我用新的布局做一些时髦的事情,但事情正在失败。变通办法?

C++ I';我用新的布局做一些时髦的事情,但事情正在失败。变通办法?,c++,memory,new-operator,C++,Memory,New Operator,我有一个非常大的、分散的类,它本质上是一个精心设计的二维链表。我希望能够“编译”它,我的意思是我希望最终确定列表,以便只进行读取访问,然后将所有元素移动到连续的内存空间中。我的大致解决方案是: #include <new> ... MyListNode* pool = new MyListNode[length]; new(&pool[position]) MyListNode(); #包括 ... MyListNode*池=新的MyListNode[长度]; 新建(&po

我有一个非常大的、分散的类,它本质上是一个精心设计的二维链表。我希望能够“编译”它,我的意思是我希望最终确定列表,以便只进行读取访问,然后将所有元素移动到连续的内存空间中。我的大致解决方案是:

#include <new>
...
MyListNode* pool = new MyListNode[length];
new(&pool[position]) MyListNode();
#包括
...
MyListNode*池=新的MyListNode[长度];
新建(&pool[position])MyListNode();
问题是我实际上有两个类,一个是用new分配的,另一个是用这个方法分配的,当我试图删除上面方法分配的任何对象时,glibc会因为一个无效指针而终止程序


自然的解决方案是创建两个类,只需使用运行时多态性来提供一个接口,但提供两个实现。等等,有没有办法,C++中的内存标准允许这种类型的伪造?p> 最明显的可能是检查对象的地址,只有当它不在您的池中时才删除它。如果我这样做,我想我可能会为类重载

操作符new
,让它总是从您的池中分配空间。通过这种方式,您可以在不复制的情况下获得连续分配,并且您的对象是统一分配的,因此您也可以统一删除它们。

显而易见的可能性是检查对象的地址,并且只有在对象不在您的池中时才将其删除。如果我这样做,我想我可能会为类重载
操作符new
,让它总是从您的池中分配空间。通过这种方式,您可以在不复制的情况下获得连续分配,并且您的对象是统一分配的,因此您也可以统一删除它们。

是否对数组中的一个对象调用
delete
?还是手动调用析构函数来镜像新位置

由于您有一个对non placement new的调用,因此您应该只有一个要删除的调用。由于对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);
//分配一个字符数组,而不是MyListNode数组。自从我们
//将使用placement new,如果MyListNode具有
//默认构造函数
MyListNode*pool=static_cast(新字符[sizeof(MyListNode)*长度);
用于(尺寸位置=0;位置<长度;++位置)
新建(&pool[position])MyListNode();
...
用于(位置=0;位置<长度;++位置)
池[位置]。~MyListNode()
删除[]静态_cast(池);

您是在数组中的一个对象上调用
delete
还是手动调用析构函数来镜像新的位置

由于您有一个对non-placement new的调用,因此您应该只有一个对delete的调用。并且由于您有n个对placement new的调用,因此您应该手动调用析构函数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);
//分配一个字符数组而不是MyListNode数组。因为
//将使用placement new,如果MyListNode具有
//默认构造函数
MyListNode*pool=static_cast(新字符[sizeof(MyListNode)*长度);
用于(尺寸位置=0;位置<长度;++位置)
新建(&pool[position])MyListNode();
...
用于(位置=0;位置<长度;++位置)
池[位置]。~MyListNode()
删除[]静态_cast(池);

您是否有一个简短但完整的示例再现问题?您是否有一个简短但完整的示例再现问题?这会导致未定义的行为。
delete[]pool
不正确,因为pool的类型为
MyListNode*
,但原始数组被分配为
char
数组。此外,在前面的for循环中已显式调用了
MyListNode
析构函数。
运算符delete[]
将是用于解除分配内存的正确函数。@CharlesBailey-谢谢。我决定通过强制转换到
char*
以镜像分配进行修复。抱歉,我的评论不完整。我的意思是您应该使用
运算符new[]
也进行分配,尽管我没有明确说明。我对您的方法的问题是,从技术上讲,您已经通过将
char
对象的存储重新用于不同类型的对象而结束了它们的生命周期。这就是为什么我支持原始存储函数方法。这会导致未定义的行为。
delete[]pool
不正确,因为
pool
具有类型
MyListNode*
,但原始数组被分配为
char
数组。此外,在前面的for循环中已显式调用了
MyListNode
析构函数。
运算符delete[]
将是用于解除分配内存的正确函数。@CharlesBailey-谢谢。我决定通过强制转换到
char*
以镜像分配进行修复。抱歉,我的评论不完整。我的意思是您应该使用
运算符new[]
也进行分配,尽管我没有明确说明。我对您的方法的问题是,从技术上讲,您已经通过将
char
对象的存储重新用于不同类型的对象而结束了它们的生命周期。这就是为什么我支持原始存储函数方法。