myVector.erase(myPtr)是否删除了myPtr指向的对象?

时间:2008-11-11 16:22:04

标签: c++ vector stl

如果我有以下代码,

Foo *f = new Foo();
vector<Foo*> vect;
vect.push_back(f);
// do stuff
vect.erase(f);

我是否创建了内存泄漏? 我想是的,但是 erase 这个词让人感觉它正在删除它。

写这个,我想知道将指针放在STL向量中是不是错误。你觉得怎么样?

7 个答案:

答案 0 :(得分:8)

是的,你创建了内存泄漏。 std :: vector和其他容器只会删除指针,它们不会释放指针指向的内存。

将指针放入标准库容器中并不罕见。但问题是,从容器中删除时必须跟踪删除它。更好,更简单的方法是使用boost :: shared_ptr:

{ 
    boost::shared_ptr<foo> f(new foo);

    std::vector< boost::shared_ptr<foo> > v;
    v.push_back(f);
    v.erase(v.begin());
} /* if the last copy of foo goes out of scope, the memory is automatically freed */

下一个C ++标准(通常称为C ++ 1x和C ++ 0x)将包含std::shared_ptr。在那里,您还可以使用速度更快的std::unique_ptr<T>,因为它不允许复制。将std::unique_ptr与c ++ 0x中的容器一起使用类似于boost中的ptr_container库。

答案 1 :(得分:4)

另一种选择是使用Boost Pointer Containers。它们的设计完全符合您的要求。

答案 2 :(得分:2)

另外还有boost :: ptr_vector container

它知道它拥有它拥有的指针,因此会自动删除它们。

作为一个很好的副作用,当访问元素时,它返回对象的引用,而不是指针使代码看起来很好。

Foo *f = new Foo();
boost::ptr_vector<Foo>  vect;
vect.push_back(f);
// do stuff
vect.erase(f);

答案 3 :(得分:2)

为了澄清指针未被删除的原因,请考虑

std::vector<char const*> strings;
strings.push_back("hello");
strings.push_back("world");
// .erase should not call delete, pointers are to literals

std::vector<int*> arrays;
strings.push_back(new int[10]);
strings.push_back(new int[20]);
// .erase should call delete[] instead of delete

std::vector<unsigned char*> raw;
strings.push_back(malloc(1000));
strings.push_back(malloc(2000));
// .erase should call free() instead of delete

一般来说,vector<T*>::erase无法猜测你是如何处置T*的。

答案 4 :(得分:1)

将指针指向标准容器绝对不是错误(然而,制作auto_ptr的容器是错误的)。是的,您需要明确删除以释放各个元素指向的内存,或者您可以使用其中一个提升smart pointers

答案 5 :(得分:1)

vector删除它包含的数据。由于你的向量包含指针,它只删除指针,而不是它们可能指向或不指向的数据。

在C ++中,一个非常普遍的规则就是在分配内存时释放内存。该向量没有分配指针指向的任何内容,因此它不能释放它。

您可能不应该首先在向量中存储指针。 在许多情况下,你最好用这样的东西:

vector<Foo> vect;
vect.push_back(Foo());
// do stuff
vect.erase(f);

当然这假设Foo是可复制的,并且它的复制构造函数不是太昂贵,但它避免了内存泄漏,并且您不必记住删除Foo对象。另一种方法是使用智能指针(例如Boost的shared_ptr),但你可能根本不需要指针语义,在这种情况下,简单的解决方案是最好的。

答案 6 :(得分:1)

STL容器不会释放你的记忆。最好的建议是使用智能指针,因为知道std :: auto_ptr不适合容器内部。我建议使用boost :: shared_ptr,或者如果您的编译器供应商支持TR1扩展(很多),您可以使用std :: tr1 :: shared_ptr。

另请注意,向量甚至不会释放为指针保留的内部存储器。即使调用clear(),std :: vectors也不会缩小范围。如果你需要缩小矢量尺寸,你将不得不求助于创建另一个矢量并交换内容。