您好,我正在尝试使用预分配内存创建对象和数组。例如我有以下代码:
int * prealloc = (int*)malloc(sizeof(Test));
Test *arr = new(prealloc) Test();
其中test定义如下:
class Test {
public:
Test() {
printf("In Constructor\n");
}
~Test() {
printf("In Destructor\n");
}
int val;
};
在这种情况下,如果我调用 delete 它实际上会释放坏内存,b/c 也许我正在使用某种类型的内存管理器,所以这肯定会导致一些问题。我在互联网上搜索,找到的唯一解决方案是显式调用析构函数,然后免费调用:
arr->~Test();
free(arr);
还有其他方法吗?有没有办法调用 delete 并告诉它只调用析构函数而不释放内存?
我的第二个问题是在使用数组时,就像前面的示例一样,您可以将预分配的内存传递给 new:
int * prealloc2 = (int*)malloc(sizeof(Test) * 10);
Test *arr2 = new(prealloc2) Test[10];
如果我调用 delete[]
,它不仅会为数组中的每个元素调用析构函数,还会释放我不想要的内存。我发现应该完成的唯一方法是遍历数组并显式调用析构函数,然后调用 free。与常规的 none 数组运算符一样,有没有办法告诉运算符只调用析构函数而不释放内存?
我注意到的一件事是数组的新运算符实际上会使用前 4 个字节来存储数组的大小(我只在 32 位构建的 visual studio 中对此进行了测试)这将帮助我了解如何数组有很多元素,但仍然存在一个问题。如果数组是指针数组怎么办?例如:
Test **arr2 = new Test*[10];
有人可以帮我解决这些问题吗
最佳答案
直接调用析构函数来销毁您使用 placement new 创建的对象是很正常的。就任何其他做事方式而言,唯一明显的替代方法是使用 Allocator 对象(至少 99% 的情况下,它只是一个围绕 placement new 并直接调用析构函数的包装器)。
一般来说,您根本不想使用new[]
。您通常希望使用 operator new
(或者可能是 ::operator new
)分配原始内存,并使用匹配的 operator delete
或 ::运算符删除
。
您在该内存中使用 new 放置创建对象,并通过直接调用析构函数来销毁它们。
关于c++ - 使用预分配的内存和数组管理析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16703168/