删除使用 placement new 构造的数组元素

deleting array elements constructed with placement new

提问人:Yousef Irshaid 提问时间:5/22/2023 更新时间:5/22/2023 访问量:61

问:

当我们创建一个类类型的动态数组时,我正在研究这种情况。据我所知,在直接调用类的非默认构造函数时,没有创建数组的方法。一种方法是正常初始化数组,然后循环并为每个对象调用非默认构造函数,但我认为这种方法存在很大的开销。在寻找解决方案后,我使用放置新发现了以下内容:

void* memory = operator new[](sizeof(Test) * 8);  // Allocate raw memory for 8 objects
Test* arr = static_cast<Test*>(memory);  //Convert to desired type
// Construct objects using placement new

for (int i = 0; i < 8; i++) {
    new (&arr[i]) Test(9);  //Assume Test has constructor Test(int)
}

// Use the initialized array

for (int i = 0; i < 8; i++) {
    arr[i].~test();  // Explicitly call destructor for each object
}
operator delete[](memory);  // Deallocate memory

我想知道是否可以按以下方式释放内存:

delete[] arr;
/*instead of 
for (int i = 0; i < 8; i++) {
    arr[i].~test();
}
operator delete[](memory); */

我在 VS2022 中测试了它,但我想确保该方法没有问题。

在 VS 调试器中,代码运行没有问题,但我担心可能的内存泄漏或删除的内存超过已经分配的内容。

C++ 动态内存分配 放置 - 新

评论

0赞 molbdnilo 5/22/2023
arr没有从 返回,因此将其传递给 是未定义的。(非正式地,由于您没有创建数组,因此无法销毁数组。new Test[size]delete[]
2赞 Daniel Langr 5/22/2023
OT:您可能希望熟悉 std::uninitialized_fill_nstd::d estroy_n 等算法,以获得更清晰的代码。
0赞 jaaq 5/22/2023
为什么不用一些创造模式来抽象呢?这样,您可以按需创建对象并自动删除它们。
1赞 fabian 5/22/2023
您的类型是可移动的吗?如果是这样,我建议简单地使用:std::vector<Test>std::vector<Test> arr; arr.reserve(8); for (int i = 0; i < 8; ++i) { arr.emplace_back(9); }
0赞 Yousef Irshaid 5/25/2023
我还是 STL 的新手,事实上,我正在尝试重新创建向量类,这就是这一切的来源

答:

5赞 Some programmer dude 5/22/2023 #1

我想知道是否可以按以下方式释放内存:

delete[] arr;

答案是否定的

为了能够使用运算符,您必须已使用运算符分配并初始化它。delete[]new[]

与 和 匹配。如果对 or 函数进行显式调用,则必须使用相应的 delete 函数。其他任何事情都会导致未定义的行为deletenewdelete[]new[]operator newoperator new[]