std :: vector破坏和意外内存泄漏 [英] std::vector Destruction and Unexpected Memory Leak

查看:614
本文介绍了std :: vector破坏和意外内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下示例:

  #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 of T when it is destroyed. Here T is int *. The destructor of int * does nothing. The storage for the int * itself is freed, but the ints 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 is x is freed, but since the destructor of a pointer is a no-op, the pointed-to int is not freed.

More to the point, vector doesn't know how the ints were allocated. They might be allocated by new int, but they could also point to elements inside an array allocated with new int[200], or they might point to malloc'd data, or they might point into a mmap'd buffer, or they might point to struct elements, or two vectors might be pointing to the same ints... etc. vector isn't smart enough to divine what you want done with these, and so it leaves them alone (additionally, giving vector logic to delete pointed-to elements would break vectors of non-pointer elements such as std::vector<int>, as you can't delete an int!)

You need to either use a std::vector<int>, or use a smart pointer in conjunction with it, eg std::vector<boost::shared_ptr<int> >. Note that using smart pointers may add overhead; with C++0x you should be able to use std::vector<std::unique_ptr<int>> in conjunction with std::move to avoid this overhead. Boost also has pointer vectors that free the pointed-to elements as you expected as well.

这篇关于std :: vector破坏和意外内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆