C ++:删除结构?

时间:2010-06-08 21:11:55

标签: c++ memory-management heap

我有一个包含指针的结构:

struct foo
{
    char* f;
    int* d;
    wchar* m;
}

我有一个指向这些结构的共享指针的向量:

vector<shared_ptr<foo>> vec;
在堆栈上分配了

vec。当它在方法结束时超出范围时,将调用其析构函数。 (对吗?)然后将调用向量中每个元素的析构函数。 (对吗?)调用delete foo只删除foo.f之类的指针,还是实际上从堆中释放了内存?

6 个答案:

答案 0 :(得分:15)

delete foo;

将删除分配给foo结构的内存,其中包括三个指针。但是如果你实现了一个明确删除它们的析构函数,指针本身指向的内存只会被删除。

答案 1 :(得分:10)

如果您已动态分配foo,例如:

foo* f = new foo;

然后delete f会破坏动态分配的foo对象,包括它包含的指针但指针指向的任何东西,如果它们确实指向动态分配的对象或对象数组。

如果您已将动态分配的foo对象(即new foo的结果)分配给shared_ptr(假设为tr1或者提升),那么最后shared_ptr引用该对象超出范围delete将在new foo最初返回的指针上自动调用。您不必手动执行此操作。

如果您的对象(foo)包含指向它所拥有的动态分配对象的指针(因此需要在foo的生命周期结束时解除分配),那么强烈建议您编写析构函数以正确的方式释放这些对象(这将取决于它们的分配方式)。

一旦编写了析构函数,就需要考虑是否需要编写复制构造函数和copy-assingment运算符。当您使用共享指针向量时,您可能决定不应复制您的对象。如果是这样,您可以将这些声明为私有,无需提供实现。

您还应该考虑一个或多个构造函数,以确保您的指针成员已初始化。如果指针成员永远不会被初始化,那么如果它们在foo的生命周期内没有被赋值,那么它们既不会为空,也不会指向有效对象,这很可能会导致析构函数出错。 / p>

答案 2 :(得分:1)

它只删除指针。

答案 3 :(得分:1)

如果delete f为堆栈分配,则不调用foo其中f是f类型的对象。如果该地址存储在共享指针中,则也不要在类型为delete f的堆分配对象上调用fooshared_ptr objets将在释放最后一个引用时为您调用delete

由于向量存储智能指针,当向量超出范围并且将调用foo析构函数并释放相关内存时,它们也将超出范围。 foo的内存只有3个指针的大小。不是那些指针包含的内容。

如果foo的成员是堆分配的,那么您需要单独delete这些成员。例如,可能在foo析构函数内,如果它们指向的内存不在对象之间共享。


  

当它在方法结束时超出范围时,将调用其析构函数。 (右?)

右。

  

这将依次调用向量中每个元素的析构函数。 (右?)

右。智能指针的析构函数。

  

还是实际上从堆中释放了内存?

它调用智能指针的析构函数,如果没有更多对该指针的引用,那么它所包含的对象将被删除,其内存将被释放。

答案 4 :(得分:1)

你的问题似乎有一些术语混淆。向量的析构函数将调用shared_ptr元素的析构函数,而后者将在内部对其存储的指针执行delete(如有必要)。

调用delete foo,其中foo是指向struct foo的指针,将调用struct foo的析构函数,然后释放*foo占用的内存。

上述struct foo的析构函数绝对没有任何作用。这是微不足道的。如果不会尝试释放struct foo::f或任何其他成员指向的内存。为什么会这样?它不会也无法知道是否应该释放该内存。

事实上,因为struct foo::~foo是微不足道的,编译器通常不会尝试调用它。

答案 5 :(得分:0)

当[vec]在方法结束时超出范围时,将调用其析构函数。 (右?)
正确

这将依次调用向量中每个元素的析构函数。 (右?)
更正,这将删除容器中的shared_ptr元素,如果它们是最后的元素,也是它们共享的项目。

调用delete foo ...?
你不能删除foo,它是一个结构。您可以删除foo的实例 调用delete会调用析构函数并释放foo结构的内存。

foo析构函数是否只删除foo :: f之类的指针,还是实际上从堆中释放了内存?
这取决于destructo,在这种情况下,你有一个默认的析构函数,所以...
不,在下面的示例代码中,您可以看到与foo关联的默认析构函数无法自动清除任何指针引用项的一些原因。

{
 char ca='a', *cb=new char;
 int *i = (int*)malloc(sizeof(int));
 foo a;
 shared_ptr<foo> b = new foo();
 a.f = &ca;
 a.d = i;
 b.f = cb;
}