C++ std::vector.clear() 是否对每个元素进行删除(空闲内存)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/594089/
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
Does std::vector.clear() do delete (free memory) on each element?
提问by Ignas Limanauskas
Consider this code:
考虑这个代码:
#include <vector>
void Example()
{
std::vector<TCHAR*> list;
TCHAR* pLine = new TCHAR[20];
list.push_back(pLine);
list.clear(); // is delete called here?
// is delete pLine; necessary?
}
Does list.clear()
call delete
on each element? I.e. do I have to free the memory before / after list.clear()
?
是否list.clear()
调用delete
每个元素?即我必须在之前/之后释放内存list.clear()
吗?
采纳答案by Ruben Bartelink
No (you need to do the delete yourself at the end as you suggest in your example as the destruction of the bald pointer doesnt do anything). But you can use a boost [or other RAII-based idiom] smart pointer to make it Do The Right Thing (auto_ptr
would not work correctly in a container as it has incompatible behaviour under copying etc.), but be sure you understand the pitfalls of such smart pointers before use. (As Benoit mentions, in this case, basic_string
is what you're really looking for here.)
不(您需要在最后自己进行删除,正如您在示例中所建议的那样,因为秃头指针的破坏不会做任何事情)。但是您可以使用 boost [或其他基于 RAII 的成语] 智能指针来使其做正确的事情(auto_ptr
在容器中无法正常工作,因为它在复制等情况下具有不兼容的行为),但请确保您了解此类智能指针使用前。(正如 Benoit 所提到的,在这种情况下,basic_string
这就是您真正要在这里寻找的东西。)
Having said that there's a need to understand the pitfalls of smart pointers, having them take care of the memory management implicitly so you dont have to do it explicitly is far less error-prone.
话虽如此,有必要了解智能指针的陷阱,让它们隐式地处理内存管理,因此您不必显式地执行它,这样不容易出错。
EDIT: Substantially revised to encompass the elements Benoit brought into his far more thorough answer, thanks to strong prodding from the Earwicker and James Matta - thanks for pushing me to do the due diligence on this!
编辑:由于来自 Earwicker 和 James Matta 的强烈刺激,大幅修改以包含 Benoit 带来的更彻底的答案的元素 - 感谢您推动我对此进行尽职调查!
回答by Beno?t
std::vector
does call the destructor of every element it contains when clear()
is called.
In your particular case, it destroys the pointer but the objects remain.
std::vector
确实会在调用时调用它包含的每个元素的析构函数clear()
。在您的特定情况下,它会破坏指针但对象仍然存在。
Smart pointers are the right way to go, but be careful. auto_ptr
cannot be used in std containers. boost::scoped_ptr
can't either. boost::shared_ptr
can, but it won't work in your case because you don't have a pointer to an object, you are actually using an array. So the solution to your problem is to use boost::shared_array
.
智能指针是正确的方法,但要小心。auto_ptr
不能在 std 容器中使用。boost::scoped_ptr
也不能。boost::shared_ptr
可以,但它在您的情况下不起作用,因为您没有指向对象的指针,您实际上是在使用数组。因此,解决您的问题的方法是使用boost::shared_array
.
But I suggest you use std::basic_string<TCHAR>
instead, where you won't have to deal with memory management, while still getting the benefits of working with a string.
但我建议你std::basic_string<TCHAR>
改用它,这样你就不必处理内存管理,同时仍然可以获得使用字符串的好处。
回答by tfinniga
Here's one way that you can tell that it doesn't - try it on a class that's not fully defined:
这是您可以判断它没有的一种方法 - 在未完全定义的类上尝试它:
#include <vector>
class NotDefined;
void clearVector( std::vector<NotDefined*>& clearme )
{
clearme.clear(); // is delete called here?
}
If this snippet compiles, then it can't be calling the destructor, because the destructor isn't defined.
如果此代码段编译,则不能调用析构函数,因为未定义析构函数。
回答by Robert Massaioli
You could just write a simple template function that does this for you:
您可以编写一个简单的模板函数来为您执行此操作:
template <class T>
void deleteInVector(vector<T*>* deleteme) {
while(!deleteme->empty()) {
delete deleteme->back();
deleteme->pop_back();
}
delete deleteme;
}
Maybe something in here is bad practice but I don't think so. It looks okay to me though comments are always nice.
也许这里的某些东西是不好的做法,但我不这么认为。虽然评论总是很好,但对我来说看起来还可以。
回答by Mehrdad Afshari
Nope. It doesn't do that since there is no guarantee you are not using the pointer anywhere else. If it wasn't a pointer variable, it would free them (by calling the destructor)
不。它不会这样做,因为不能保证您不会在其他任何地方使用指针。如果它不是指针变量,它将释放它们(通过调用析构函数)
回答by Head Geek
You might also be able to use the Boost Pointer Container Library. Not specifically recommended here (again because you're using arrays instead of single objects, though std::string
would take care of that), but it's a useful and little-known library that solves the problem stated in the title.
您也可以使用Boost Pointer Container Library。这里没有特别推荐(再次因为您使用的是数组而不是单个对象,尽管std::string
会处理这个问题),但它是一个有用且鲜为人知的库,可以解决标题中所述的问题。