使用链式动态分配删除运算符

时间:2015-10-08 08:52:34

标签: c++ memory-management

假设我有两个名为classA和classB的类。我创建了一个指向classA的指针,然后使用new运算符动态分配单个对象,如下所示:

classA *ptrA = new classA

classA具有指向classB的类型指针的成员,并且在其默认构造函数中,它在堆上分配类型为classB的对象数组,如下所示:

memberOfA = new classB[10]

并且为了进一步复杂化,classB有一个类型为int *的成员变量,并且在其默认构造函数中,它在堆上全部涂覆整数数组,如下所示:

memberOfB = new int[100]

现在,如果我使用delete ptrA在ptrA上调用delete,编译器将如何解除分配memberOfAmemberOfB分配的内存。

3 个答案:

答案 0 :(得分:2)

  

现在,如果我使用delete ptrA在ptrA上调用delete,编译器将如何解除分配memberOfAmemberOfB分配的内存。

当您调用delete ptrA时,编译器将调用classA的析构函数。如果该析构函数不是delete [] memberOfA,那么您就会泄漏memberOfA并因此泄露memberOfB

如果您使用自动内存管理(SBRM / RAII)代替手动内存管理(newdelete),那么您将不必编写任何析构函数和您分配的资源将按预期释放,例如:

std::unique_ptr<classA> ptrA(new classA);
std::unique_ptr<classB[]> memberOfA(new classB[10]);
std::unique_ptr<int[]> memberOfB(new int[100]);

这实际上是现代C ++的方法。代码变得更容易理解,因为指针的所有权语义是在它们的类型中写入的,并且没有析构函数。更好的方法是使用std::make_unique(...)代替new,但为了简单起见,我将其排除在外。

答案 1 :(得分:1)

如果您在memberOfAmemberOfB的攻略者中放置delete[],则只会取消分配

classAclassB。所以,如果你编写了classA的析构函数,那么它就会释放memberOfA指向的内存:

classA::~classA() {
    delete [] memberOfA;
}

在这种情况下,析构函数将释放数组,调用memberOfA中条目指向的元素的析构函数。 classB

的析构函数也是如此
classB::~classB() {
    delete [] memberOfB;
}

请记住,使用new必须在某个时候与后续的delete配对,否则就会看到泄漏。也许你应该考虑一个智能指针类:unique_ptrshared_ptr

如果您的设计允许classAclassB对阵列使用unique_ptrshared_ptr,那么泄漏的大部分危险都会被克服:< / p>

std::unique_ptr<classB[]> memberOfA(new classB[10]);

如果您感兴趣的是删除顺序,那么调用delete ptrA将导致调用classA的析构函数,如果我们假设它是按照上面的提示实现的(使用delete [])然后delete []运算符将按递减地址顺序调用所有成员的析构函数,引用标准,草案N3690,第5.3.5 / 6节:

  

如果delete-expression的操作数的值不是空指针值,则delete-expression将调用该对象的析构函数(如果有)或要删除的数组的元素。在数组的情况下,元素将按地址递减的顺序销毁(即,与构造函数完成的顺序相反;见12.6.2)。

这当然会导致为每个元素调用classB的析构函数,它将再次使用delete [] memberOfB来释放指向整数的数组。

答案 2 :(得分:1)

它不会......你应该通过实现析构函数来做到这一点!您可以使用delete []运算符来完成此操作。

classA::~classA() {
   delete [] memberOfA;
}

 classB::~classB() {
   delete [] memberOfB;
 }

然后你删除ptrA执行的顺序是:

call classA::~classA()
call classB::~classB() on each of the elements of memberOfA
deallocate memory for the array of ints pointed by memberofB
deallocate memory for the array of memberofA
deallocate memory for classA

在某些情况下,释放内存实际上可能会发生在后期阶段。

或者,如果您不需要使用指针,请使用数组或向量来保存元素。

class classB
{
...
std::array<int,100> memberOfB;
...
};
class classA
{
...
std::array<classB,10> memberOfA;
...
};

std::unique_ptr<A> ptrA(new classA)