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

huangapple go评论57阅读模式
英文:

deleting array elements constructed with placement new

问题

I was looking into the case when we create a dynamic array of class types. As I know there isn't a method to create the array while calling a non-default constructor of the class directly. One way to do so is initializing the array with normally and then looping and calling the non-default constructor for each object, but I think there is significant overhead in that approach. After looking for a solution, I found the following using the placement new:

void* memory = operator new[](sizeof(Test) * 8);  // 分配8个对象的原始内存
Test* arr = static_cast<Test*>(memory);  // 转换为所需类型
// 使用placement new构造对象

for (int i = 0; i < 8; i++) {
    new (&arr[i]) Test(9);  // 假设Test有构造函数Test(int)
}

// 使用初始化后的数组

for (int i = 0; i < 8; i++) {
    arr[i].~Test();  // 显式调用每个对象的析构函数
}
operator delete[](memory);  // 释放内存

I am wondering if it is possible to deallocate the memory as the following:

delete[] arr;
/*而不是
for (int i = 0; i < 8; i++) {
    arr[i].~Test();
}
operator delete[](memory); */

I tested it in VS2022 but I want to make sure that there aren't problems with the approach.

In VS debugger the code was running without problems, but I am worried about possible memory leaks or deleting more than what's already allocated.

英文:

I was looking into the case when we create a dynamic array of class types. As I know there isn't a method to create the array while calling a non-default constructor of the class directly. One way to so is initializing the array with normally and then looping and calling the non-default constructor for each object, but I think there is significant overhead in that approach. After looking for a solution, I found the following using the placement new:

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

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

// Use the initialized array

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

I am wondering if it is possible to deallocate the memory as the following:

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

I tested it in VS2022 but I want to make sure that there aren't problems with the approach.

In VS debugger the code was running without problems, but I am worried about possible memory leaks or deleting more than what's already allocated.

答案1

得分: 5

The answer is no.

To be able to use the delete[] operator you must have allocated and initialized it with the new[] operator.

Match delete with new, and delete[] with new[]. If you do an explicit call to the operator new or operator new[] functions, you must use the corresponding delete function. Anything else leads to undefined behavior.

英文:

> I am wondering if it is possible to deallocate the memory as the following:
>
> delete[] arr;

The answer is no.

To be able to use the delete[] operator you must have allocated and initialized it with the new[] operator.

Match delete with new, and delete[] with new[]. If you do an explicit call to the operator new or operator new[] functions, you must use the corresponding delete function. Anything else leads to undefined behavior.

huangapple
  • 本文由 发表于 2023年5月22日 19:26:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76305669.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定