std :: vector破坏和意外内存泄漏 [英] std::vector Destruction and Unexpected Memory Leak
问题描述
请考虑以下示例:
#include< vector&
!)
class Foo {
std :: vector< int *> v;
public:
Foo(){
this-> v.push_back(new int(23));
this-> v.push_back(new int(24));
this-> v.push_back(new int(25));
}
〜Foo(){
}
};
int main(){
Foo f;
return 0;当f超出main()中的范围时,调用f的析构函数,如果f超过范围,则调用f()这应间接释放fv根据 this ,向量v的每个元素的析构函数现在应该
但是,当我在valgrind中运行这个程序时,我发现int *不会被释放。
$ valgrind --leak-check = full ./a.out
我在这里缺少了什么?
解决方案
std :: vector< T& ; c>当它被销毁时,确实调用
T
的析构函数。这里T
是int *
。析构函数int *
什么都不做。int *
本身的存储被释放,但它们指向的int
不是。
考虑:
int main(){
int * new int(23);
return 0;
}
当
x
超出范围时,其析构函数确实被调用,并且指针的存储为x
被释放,但由于指针的析构函数是无操作,所以指向的int
不会被释放。
更多的是,
向量
不知道int
s已分配。它们可以由new int
分配,但也可以指向分配有new int [200]的数组中的元素
,或者它们可能指向malloc
'数据,或者它们可能指向一个mmap
它们可能指向struct元素,或者两个向量可能指向同一个int
s ...等。向量
不够聪明,不足以想象你想用这些做什么,所以它让它们孤独(另外,给予向量
删除指向的元素的逻辑将打破非-pointer元素如std :: vector< int>
,因为您不能delete
c> int
您需要使用
std :: vector< int>
,或者结合使用智能指针,例如std :: vector< boost :: shared_ptr< int> >
。请注意,使用智能指针可能会增加开销;与C ++ 0x应该能够使用std :: vector< std :: unique_ptr< int>>
与std :: move
以避免此开销。 Boost还具有指针向量,可自由释放指向的元素预期也一样。Consider the following example:
#include <vector> class Foo { std::vector<int*> v; public: Foo() { this->v.push_back(new int(23)); this->v.push_back(new int(24)); this->v.push_back(new int(25)); } ~Foo() { } }; int main() { Foo f; return 0; }
When f goes out of scope in main(), f's destructor is called, which should indirectly free f.v. According to this, the destructor of each element of the vector v should now be called.
However, when I run this program in valgrind, I find that the int*'s were not deallocated.
$ valgrind --leak-check=full ./a.out
What am I missing here?
解决方案
std::vector<T>
does indeed call the destructor ofT
when it is destroyed. HereT
isint *
. The destructor ofint *
does nothing. The storage for theint *
itself is freed, but theint
s they point to are not.Consider:
int main() { int *x = new int(23); return 0; }
This exhibits the same problem; when
x
goes out of scope, its destructor is indeed called, and the storage for the pointer that isx
is freed, but since the destructor of a pointer is a no-op, the pointed-toint
is not freed.More to the point,
vector
doesn't know how theint
s were allocated. They might be allocated bynew int
, but they could also point to elements inside an array allocated withnew int[200]
, or they might point tomalloc
'd data, or they might point into ammap
'd buffer, or they might point to struct elements, or two vectors might be pointing to the sameint
s... etc.vector
isn't smart enough to divine what you want done with these, and so it leaves them alone (additionally, givingvector
logic to delete pointed-to elements would break vectors of non-pointer elements such asstd::vector<int>
, as you can'tdelete
anint
!)You need to either use a
std::vector<int>
, or use a smart pointer in conjunction with it, egstd::vector<boost::shared_ptr<int> >
. Note that using smart pointers may add overhead; with C++0x you should be able to usestd::vector<std::unique_ptr<int>>
in conjunction withstd::move
to avoid this overhead. Boost also has pointer vectors that free the pointed-to elements as you expected as well.这篇关于std :: vector破坏和意外内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!