std::vector.clear() 是否对每个元素进行删除(释放内存)?

发布于 2024-07-14 05:19:37 字数 377 浏览 6 评论 0原文

考虑以下代码:

#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?
}

list.clear() 是否对每个元素调用 delete ? 即我是否必须在 list.clear() 之前/之后释放内存?

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()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一绘本一梦想 2024-07-21 05:19:37

当调用 clear() 时,std::vector 确实会调用它包含的每个元素的析构函数。
在您的特定情况下,它会销毁指针,但对象仍然存在。

智能指针是正确的方法,但要小心。 auto_ptr 不能在 std 容器中使用。 boost::scoped_ptr 也不能。 boost::shared_ptr 可以,但在你的情况下它不起作用,因为你没有指向对象的指针,你实际上使用的是数组。 因此,解决您问题的方法是使用 boost::共享数组

但我建议您使用 std::basic_string 来代替,这样您就不必处理内存管理,同时仍然可以获得使用字符串的好处。

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.

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.

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.

神也荒唐 2024-07-21 05:19:37

否(您需要按照示例中的建议在最后自行删除,因为秃头指针的销毁不会执行任何操作)。 但是您可以使用 boost [或其他基于 RAII 的习惯用法] 智能指针来使其做正确的事情(auto_ptr 在容器中无法正常工作,因为它在复制等情况下具有不兼容的行为),但在使用之前请确保您了解此类智能指针的陷阱。 (正如 Benoit 提到的,在这种情况下,basic_string 才是您真正要寻找的。)

话虽如此,有必要了解智能指针的陷阱,让它们负责内存管理隐式地这样你就不必显式地这样做,这样就不容易出错。

编辑:在 Earwicker 和 James Matta 的强烈推动下,进行了实质性修改,以包含 Benoit 纳入其更彻底答案中的元素 - 感谢您推动我对此进行尽职调查!

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.)

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!

咆哮 2024-07-21 05:19:37

您可以通过以下一种方法来判断它是否存在 - 在未完全定义的类上尝试:

#include <vector>
class NotDefined;

void clearVector( std::vector<NotDefined*>& clearme )
{
    clearme.clear();    // is delete called here?
}

如果此代码片段可以编译,则它不能调用析构函数,因为析构函数未定义。

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.

半步萧音过轻尘 2024-07-21 05:19:37

没有。 它不会这样做,因为不能保证您不会在其他地方使用指针。 如果它不是指针变量,它将释放它们(通过调用析构函数)

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)

爱殇璃 2024-07-21 05:19:37

您可以编写一个简单的模板函数来为您执行此操作:

template <class T>
void deleteInVector(vector<T*>* deleteme) {
    while(!deleteme->empty()) {
        delete deleteme->back();
        deleteme->pop_back();
    }

    delete deleteme;
}

也许这里的某些内容是不好的做法,但我不这么认为。 虽然评论总是很好,但对我来说看起来还不错。

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.

折戟 2024-07-21 05:19:37

您也许还可以使用 Boost 指针容器库。 这里没有特别推荐(同样是因为您使用的是数组而不是单个对象,尽管 std::string 会解决这个问题),但它是一个有用且鲜为人知的库,可以解决所述问题在标题中。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文