std :: vector销毁和意外的内存泄漏

rus*_*hki 2 c++ memory-leaks 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;
}
Run Code Online (Sandbox Code Playgroud)

当f超出main()中的范围时,会调用f的析构函数,它应该间接释放fv.根据这个,现在应该调用向量v的每个元素的析构函数.

但是,当我在valgrind中运行这个程序时,我发现int*没有被释放.

$ valgrind --leak-check=full ./a.out
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?

bdo*_*lan 10

std::vector<T>确实称它为破坏后的析构函数T.这Tint *.析构函数int *什么都不做.自己的存储int *被释放,但int他们指出的不是.

考虑:

int main() {
   int *x = new int(23);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这表现出同样的问题; 当x超出范围时,它的析构函数确实调用,并为存储指针是x被释放,但由于指针的析构函数是一个无操作时,指向的 int是不会释放.

更重要的是,vector不知道ints是如何分配的.它们可能被分配new int,但它们也可以指向分配的数组内的元素new int[200],或者它们可能指向malloc'd数据,或者它们可能指向mmap'd缓冲区,或者它们可能指向struct元素,或者两个向量可能指向相同int的......等等vector不够聪明,不能用你想要的东西vector来划分它们,所以它让它们独自一人(另外,给逻辑删除指向的元素会破坏非指针元素的向量)比如std::vector<int>,你不能delete一个int!)

您需要使用a std::vector<int>,或者使用智能指针,例如std::vector<boost::shared_ptr<int> >.请注意,使用智能指针可能会增加开销; 使用C++ 0x,您应该能够std::vector<std::unique_ptr<int>>结合使用std::move以避免这种开销.Boost还有指针向量,可以按预期释放指向的元素.