C++ std::向量破坏和意外内存泄漏

C++ std::向量破坏和意外内存泄漏,c++,memory-leaks,vector,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() { }

考虑以下示例:

#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;
}
int a = 5;
int* i = &a;
if (true)
{
   int* j = i;
} //j goes out of scope, should *i and a be deleted? no.
我错过了什么

现在应该调用向量
v
的每个元素的析构函数

是:向量中存储的
int*
对象被销毁(这实际上是一个否定操作)。容器中指针指向的对象不会被销毁

考虑以下同样有效的计划:

{
    int x;
    std::vector<int*> v;
    v.push_back(&x);
}   // x cannot be delete'd because it isn't dynamically allocated.
{
int x;
std::向量v;
v、 向后推(&x);
}//无法删除x,因为它不是动态分配的。

您应该使用智能指针,如
std::unique_ptr
shared_ptr
,这样就不必担心内存管理(不要使用
std::auto_ptr
;它与标准库容器不兼容,因为它实际上不可复制)。如果不使用智能指针,则需要自己销毁动态对象;正确执行此操作相当困难。

向量的每个元素都是一个
int*
。当
int*
被销毁时,该语言不会自动对其调用
delete
。换句话说,被销毁的是指针,而不是指针对象。

std::vector
确实在销毁时调用了
T
的析构函数。这里的
T
int*
int*
的析构函数不执行任何操作。
int*
本身的存储被释放,但它们指向的
int
s未被释放

考虑:

int main() {
   int *x = new int(23);
   return 0;
}
这表现出同样的问题;当
x
超出范围时,它的析构函数确实被调用,指针
x
的存储被释放,但由于指针的析构函数是no op,指向的
int
不会被释放

更重要的是,
vector
不知道
int
s是如何分配的。它们可以由
new int
分配,但也可以指向用
new int[200]
分配的数组中的元素,或者指向
malloc
'd数据,或者指向
mmap
'd缓冲区,或者指向结构元素,或者两个向量可能指向相同的
int
s。。。等等。
vector
不够聪明,无法预测你想用它们做什么,因此它将它们放在一边(另外,给
vector
逻辑删除指向元素会破坏非指针元素的向量,例如
std::vector
,因为你不能
删除
一个
int
!)


您需要使用
std::vector
,或者将智能指针与之结合使用,例如
std::vector
。请注意,使用智能指针可能会增加开销;使用C++0x,您应该能够将
std::vector
std::move
结合使用,以避免这种开销。Boost还可以像您期望的那样释放指向元素。

因为您使用的是
new
关键字,整数是在堆上而不是堆栈上分配的。换句话说,它们是动态分配的。换言之,你需要清理后,它

指针类型的“析构函数”就是简单地删除该指针。它不接触指针存储的内存地址处的数据。考虑下面的例子:

#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;
}
int a = 5;
int* i = &a;
if (true)
{
   int* j = i;
} //j goes out of scope, should *i and a be deleted? no.
因此,您需要在析构函数中执行此操作:

std::vector<int*>::iterator iter;
for (iter = v.begin(); iter != v.end(); iter++)
{
   delete *iter;
}
std::vector::iter;
对于(iter=v.begin();iter!=v.end();iter++)
{
删除*国际热核实验堆;
}

注意,
unique\u ptr
只能在STL容器中使用,如果您使用C++0x,并且在插入项目时使用
std::move
。是的,这回答了我的问题。int*指向的内存不会被释放,尽管指针本身会被释放。非常感谢。可能重复的