C++ 我应该删除 vector<string> 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/993590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I delete vector<string>?
提问by IamDeveloper
I've painfully learned during last few days a lot about programming in c++.
I love it :)
I know I should release memory - the golden "each malloc=free" or "each new=delete" rules exist now in my world, but I'm using them to rather simple objects.
What about vector ? Wherever I can, I'm using vector.clear() but that clearly isn't enough, because I'm having huge memory leaks.
Could you guide me on how should I treat this thing?
在过去的几天里,我痛苦地学到了很多关于 C++ 编程的知识。
我喜欢它 :)
我知道我应该释放内存——黄金“每个 malloc=free”或“每个 new=delete”规则现在存在于我的世界中,但我将它们用于相当简单的对象。
向量呢?无论我在哪里,我都在使用 vector.clear() 但这显然还不够,因为我有巨大的内存泄漏。
你能指导我如何对待这件事吗?
*Edit
Thanks, your comments made me think about the alghorithm of this application and I'll be able to eliminate the vector totally. :O
Sorry - I started explaining what is my use case here and I found out what I really need. It's like that when you code last 3 days for 18 hours a day :|
*Edit 2
This is crazy. By small changes in code, I've eliminated memory usage from 2x130 mb (constantly growing) into 2x 13,5mb, constant size. Thanks for making me think about that in another way.
*编辑
谢谢,您的评论让我想到了这个应用程序的算法,我将能够完全消除向量。:O
对不起 - 我开始在这里解释我的用例是什么,我发现了我真正需要的东西。就像你每天 18 小时持续 3 天编码一样:| *编辑2
这太疯狂了。通过对代码的微小更改,我将内存使用量从 2x130 mb(不断增长)减少到 2x 13.5mb,大小不变。谢谢你让我以另一种方式思考这个问题。
Btw. such self code review got a name - anyone remember that? It's when you ask anyone (even your mother or dog) and start explaining what's your problem - and suddenly you solve this 5 hour problem yourself, just by trying to look at it from other point of view, or just by trying to summarize what's it all about. I often find myself being catched on that...
顺便提一句。这种自我代码有一个名字——有人记得吗?当你问任何人(甚至你的母亲或狗)并开始解释你的问题时 - 突然你自己解决了这个 5 小时的问题,只是试图从其他角度看待它,或者只是试图总结它是什么所有关于。我经常发现自己被抓住了...
回答by Dima
The rule is that when you clear a vector of objects, the destructor of each element will be called. On the other hand, if you have a vector of pointers, vector::clear()
will not call delete
on them, and you have to delete them yourself.
规则是,当您清除对象向量时,将调用每个元素的析构函数。另一方面,如果您有一个指针向量,vector::clear()
则不会调用delete
它们,您必须自己删除它们。
So if all you have is a vector of strings, and not pointers to strings, then your memory leaks must be caused by something else.
因此,如果您拥有的只是一个字符串向量,而不是指向字符串的指针,那么您的内存泄漏一定是由其他原因引起的。
回答by rlbond
You don't need to be doing this. std::string cleans itself up, so the strings are not your problem. Remember that YOU didn't use new
so YOU don't have to use delete
.
你不需要这样做。std::string 会自行清理,因此字符串不是您的问题。请记住,您没有使用,new
因此您不必使用delete
.
You should probably learn about RAII- it makes allocation and deallocation much simpler. You'll avoid memory leaks this way.
您可能应该了解RAII- 它使分配和解除分配更加简单。您将通过这种方式避免内存泄漏。
回答by avakar
Calling v.clear()
will destroy all objects that are currently held inside v
, but it will not release the memory (it is assumed that the vector will soon be filled again).
调用v.clear()
将销毁当前保存在 中的所有对象v
,但不会释放内存(假设向量很快会再次被填充)。
If you really want to free the memory, the idiom is
如果你真的想释放内存,成语是
vector<string>().swap(v);
This will create a new (temporary) vector and swap its contents with v
. The temporary vector is then destroyed, freeing the memory along with it.
这将创建一个新的(临时)向量并将其内容与v
. 然后临时向量被销毁,同时释放内存。
回答by Martin York
The vector (like all standard containers) owns the objects inside it.
So it is responsible for destroying them.
向量(与所有标准容器一样)拥有其中的对象。
所以它负责摧毁它们。
Note: If you vector contains pointers then it owns the pointers (not what the pointers point at). So these need to be deleted. But there are easier ways.
注意:如果向量包含指针,则它拥有指针(而不是指针指向的内容)。所以这些都需要删除。但还有更简单的方法。
You could use a vector of smart pointers. In fact you should be using some form of smart pointer for nearly everything. If you are using pointers you are probably still programming like a C programmer.
您可以使用智能指针向量。事实上,您应该对几乎所有事物都使用某种形式的智能指针。如果您使用指针,您可能仍然像 C 程序员一样编程。
So:
所以:
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.
But it sounds like you need to start thinking about learning about smart pointers.
但听起来您需要开始考虑学习智能指针。
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.
回答by ASk
Deleting elements from STL containers is guaranteed to call destructors on these elements.
However, if you have a container of some pointer-to-T
type, then you still have to free the pointed-to memory yourself (in this case, the "destructor" for the pointer gets called, which is a no-operation).
从 STL 容器中删除元素一定会在这些元素上调用析构函数。但是,如果您有某种pointer-to-T
类型的容器,那么您仍然必须自己释放指向的内存(在这种情况下,将调用指针的“析构函数”,这是一个无操作)。
If you do not want to manually manage memory in this case, consider using a smart-pointer solutionor a pointer container.
回答by Timo Geusch
If you have a vector and it goes out of scope, all objects in the vector are destroyed. There isn't really a need to call clear() unless you want to dump the contents and reuse the vector.
如果您有一个向量并且它超出了范围,则该向量中的所有对象都将被销毁。除非您想转储内容并重用向量,否则实际上没有必要调用 clear() 。
However if you by any chance are using something like a vector then the destructor of the objects being pointed to will not be called as the vector destructor doesn't follow the indirections represented by the pointers.
但是,如果您有机会使用类似向量的东西,那么将不会调用所指向对象的析构函数,因为向量析构函数不遵循指针表示的间接寻址。
All that said, have you actually confirmed that you've got genuine memory leaks and that they are caused by the data in the vector?
说了这么多,你真的确认你有真正的内存泄漏并且它们是由向量中的数据引起的吗?
回答by Zan Lynx
As rlbond suggested, use RAII.
正如 rlbond 建议的那样,使用 RAII。
It's a good rule of thumb to never put new and delete calls into your main code flow. Always try to put them into objects so that the object destructor can free what needs to be freed. In this way, you avoid needing to remember to call delete and it makes your code exception safe (assuming that you make your object's operations exception safe).
永远不要将 new 和 delete 调用放入主代码流中是一个很好的经验法则。始终尝试将它们放入对象中,以便对象析构函数可以释放需要释放的内容。通过这种方式,您无需记住调用 delete 并且使您的代码异常安全(假设您使对象的操作异常安全)。
For example, if you had a vector of pointers to STL strings or C-style character arrays, put that into a StringContainer (use a better name) and have the StringContainer hold a vector and in the StringContainer destructor run a for loop to delete each string in the vector.
例如,如果您有一个指向 STL 字符串或 C 样式字符数组的指针向量,请将其放入 StringContainer(使用更好的名称)并让 StringContainer 持有一个向量,然后在 StringContainer 析构函数中运行 for 循环以删除每个向量中的字符串。
You can make the vector inside the StringContainer a public member and mess around with it directly, but it's even better design to make it private or protected and add some member functions to manage the string* vector.
您可以将 StringContainer 中的向量设置为公共成员并直接使用它,但更好的设计是将其设为私有或受保护并添加一些成员函数来管理 string* 向量。
So your main C++ program should never see a new or delete anywhere. Instead it should have a lot of stack allocated objects, auto_ptrs and shared_ptrs.
所以你的主 C++ 程序不应该在任何地方看到 new 或 delete 。相反,它应该有很多堆栈分配的对象,auto_ptrs 和 shared_ptrs。
回答by Ryan Oberoi
Give a use case. The destructor on the string is getting called by vector::clear. Your problem lies elsewhere my friend.
给出一个用例。字符串上的析构函数被 vector::clear 调用。你的问题出在别处,我的朋友。
also check out:
还请查看:
Does std::vector.clear() do delete (free memory) on each element?