我应该删除vector <string>吗?</string>

时间:2009-06-14 19:45:25

标签: c++ memory-management

我在过去的几天里痛苦地学习了很多关于c ++编程的知识 我喜欢它:) 我知道我应该释放记忆 - 现在我的世界中存在着金色的“每个malloc = free”或“每个new = delete”规则,但我将它们用于相当简单的对象。
矢量怎么样?无论我在哪里,我都在使用vector.clear(),但这显然是不够的,因为我有大量的内存泄漏。
你能指导我如何对待这件事吗?

*编辑
谢谢,你的评论让我想到了这个应用程序的算法,我将能够完全消除向量。 :o
对不起 - 我开始在这里解释我的用例是什么,我发现了我真正需要的东西。就像每天18小时编码最后3天一样:| *编辑2
这太疯狂了。通过代码的微小变化,我将内存使用量从2x130 mb(不断增长)消除到2x 13,5mb,恒定大小。谢谢你让我以另一种方式思考这个问题。

顺便说一下。这样的自我代码审查有一个名字 - 有人记得吗?当你问任何人(甚至你的母亲或狗)并开始解释你的问题时 - 突然你自己解决了这个5小时的问题,只是试图从其他角度来看待它,或者只是试图总结它是什么所有关于。我经常发现自己被抓住了......

8 个答案:

答案 0 :(得分:22)

规则是当你清除一个对象向量时,将调用每个元素的析构函数。另一方面,如果你有一个指针向量,vector::clear()将不会在它们上面调用delete,你必须自己删除它们。

因此,如果你拥有的是一个字符串向量,而不是指向字符串的指针,那么你的内存泄漏必须由其他东西引起。

答案 1 :(得分:9)

你不需要这样做。 std :: string清理自己,所以字符串不是你的问题。请记住,您没有使用new,因此您不必使用delete

您应该了解RAII - 它使分配和释放更加简单。你会以这种方式避免内存泄漏。

答案 2 :(得分:7)

调用v.clear()将销毁当前保存在v内的所有对象,但它不会释放内存(假设该向量很快将再次填充)。

如果你真的想释放记忆,那么成语就是

vector<string>().swap(v);

这将创建一个新的(临时)向量,并将其内容与v交换。然后销毁临时矢量,释放内存。

答案 3 :(得分:5)

向量(与所有标准容器一样)拥有其中的对象 所以它负责摧毁它们。

注意:如果vector包含指针,那么它拥有指针(而不是指针指向的指针)。所以这些都需要删除。但是有更简单的方法。

您可以使用智能指针向量。事实上,你应该使用某种形式的智能指针几乎所有东西。如果你使用指针,你可能仍然像C程序员一样编程。

所以:

std::vector<int>    data; // clear is fine.

std::vector<int*>   data1; // Now things need to be deleted.
// alternative 1:
std::vector<boost::shared_ptr<int> >  data2; // The shared pointer will auto
                                             // delete the pointer.
// alternative 2:
boost::ptr_vector<int>  data3;               // Here the container knows that
                                             // it is holding pointers and will
                                             // auto de-reference them when you
                                             // its members.

但听起来你需要开始考虑学习智能指针。

int*  x = new int(5);
// Do stuff.
*x = 8;
delete x;

// --- Instead use a smart pointer:
std::auto_ptr<int>  x(new int(5));
// Do stuff.
*x = 8;
// No delete (the auto ptr handles it.

答案 4 :(得分:5)

保证从STL容器中删除元素可以在这些元素上调用析构函数。 但是,如果你有一个pointer-to-T类型的容器,那么你仍然必须自己释放指向内存(在这种情况下,指针的“析构函数”被调用,这是一个无操作)

如果您不想在这种情况下手动管理内存,请考虑使用smart-pointer solutionpointer container

答案 5 :(得分:2)

如果你有一个向量并且它超出范围,则向量中的所有对象都将被销毁。除非您想要转储内容并重用向量,否则不需要调用clear()。

但是,如果您有任何机会使用类似向量的东西,那么指向的对象的析构函数将不会被调用,因为向量析构函数不遵循指针所代表的间接。

所有这一切,你真的确认你有真正的内存泄漏,并且它们是由向量中的数据引起的吗?

答案 6 :(得分:0)

提供一个用例。字符串上的析构函数被vector :: clear调用。你的问题出在我朋友的其他地方。

也请查看:

Does std::vector.clear() do delete (free memory) on each element?

答案 7 :(得分:0)

正如rlbond所建议的那样,使用RAII。

从不将新的和删除调用放入主代码流中是一个很好的经验法则。总是尝试将它们放入对象中,以便对象析构函数可以释放需要释放的内容。通过这种方式,您可以避免需要记住调用delete并使代码异常安全(假设您使对象的操作异常安全)。

例如,如果您有一个指向STL字符串或C样式字符数组的指针向量,请将其放入StringContainer(使用更好的名称)并让StringContainer保存一个向量,并在StringContainer析构函数中运行for循环删除向量中的每个字符串。

你可以使StringContainer中的向量成为一个公共成员并直接使用它,但更好的设计是将其设为私有或受保护,并添加一些成员函数来管理字符串*向量。

所以你的主要C ++程序永远不应该在任何地方看到新的或删除。相反,它应该有很多堆栈分配的对象,auto_ptrs和shared_ptrs。