2010-06-08 68 views
6

我有一个包含指针一个结构:C++:删除一个结构?

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

我有共享指针的这些结构的载体:

vector<shared_ptr<foo>> vec; 

vec是在堆栈上分配。当它在方法结束时超出范围时,它的析构函数将被调用。 (右?)这将依次调用向量中每个元素的析构函数。 (对吗?)delete foo是否只删除了指针,如foo.f,还是它实际上从堆中释放内存?

回答

15
delete foo; 

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

+2

或者,也可以将f,d和m更改为使用自动或共享指针。 – 2010-06-08 21:19:02

1

它只删除指针。

1

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

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

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


当流出的在方法结束范围,其析构函数将被调用。 (对吧?)

没错。

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

没错。智能指针的析构函数。

还是它真的从堆中释放内存?

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

1

你的问题似乎出现了一些术语混淆。矢量的析构函数将调用shared_ptr元素的析构函数,而元素将依次在其存储的指针(如果需要)上执行delete

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

上述struct foo的破坏者完全没有。这是微不足道的。如果不会尝试释放由struct foo::f指向的内存或任何其他成员。为什么呢?它不知道该内存是否应该被释放。

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

10

如果您动态分配foo,如:

foo* f = new foo; 

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

如果您分配一个动态分配的foo对象(即的new foo结果)为shared_ptr(假设TR1或升压),那么当最后shared_ptr指的是物体超出范围delete将被称为上的指针最初自动返回new foo。您不必手动执行此操作。

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

一旦你写了一个析构函数,你需要考虑是否需要编写一个拷贝构造函数和复制操作符。当你使用共享指针向量时,你可能会决定不应该复制你的对象。如果是这样,你可以声明这些是私有的,不需要提供实现。

您还应该考虑一个或多个构造函数来确保您的指针成员已初始化。如果指针成员从未初始化,那么如果它们在foo的生命周期中未分配给它们,则它们既不会为空也不会指向有效的对象,这可能会在析构函数中导致错误。

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; 
}