【问题标题】:storing allocated objects in stl list将分配的对象存储在 stl 列表中
【发布时间】:2014-09-18 04:34:51
【问题描述】:

我目前正在研究四叉树数据结构。

我在 C++ 中采用面向对象的方法。我有一个四叉树的类,我的类有一个指向名为 node 的结构的指针,该结构使用 new 关键字分配。

该结构包含一个 stl 列表子项。每次我拆分四叉树时,我都会在列表中填充:

节点 *newnode = 新节点。

p_node->children.push_back(*newnode) //其中p_node是父节点

因此,由于我使用了 new 我必须释放内存。 我这样做的方式是我正在遍历树并从每个 stl 列表中清除子项,然后删除根。但是 valgrind 告诉我我有内存泄漏。我想知道是否有人可以解释如何释放动态分配并存储在 stl 列表中的数据。

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    您的列表必须存储对象,而不是指针(从您在调用 push_back() 时遵循 newnode 这一事实可以看出):

    list<node> p_node;
    

    当您push_back() 时,您正在存储源对象的副本,因此您必须使用new 分配您分配的原始对象delete,否则它将被泄露:

    node *newnode = new node;
    p_node.push_back(*newnode); // <-- makes a copy
    delete node; // <-- must free original
    

    可以简化为:

    node newnode;
    p_node.push_back(newnode);
    

    甚至:

    p_node.push_back(node());
    

    话虽如此,如果你想在你的列表中存储指针,你必须这样做:

    list<node*> p_node;
    ...
    node *newnode = new node;
    p_node.push_back(newnode);
    

    然后遍历p_node用完对象删除:

    for (list<node*>::iterator i = p_node.begin(); i != p_node.end(); ++i)
        delete *i;
    p_node.clear();
    

    如果您使用 C++11,则可以使用 std::unique_ptrstd::shared_ptr 代替裸指针,因为两者都是容器安全的(与 std::auto_ptr 不同,后者不是)。让 STL 为您管理内存,完成节点后无需遍历:

    list<unique_ptr<node>> p_node;
    ...
    unique_ptr<node> newnode(new node);
    p_node.push_back(newnode);
    

    list<shared_ptr<node>> p_node;
    ...
    auto newnode = make_shared<node>();
    p_node.push_back(newnode);
    

    【讨论】:

    • 非常感谢。这让我明白了很多事情。
    【解决方案2】:

    我在这里看到了一系列问题

    1) 为什么要“新建”一个指针而不是传递一个对象? 像

    Node n;
    parent_node.push_back(n); // Copy or move constructor here
    

    2) 为什么,为什么要裸指针?!?不要这样做!如果您需要指针语义,请使用智能指针并管理您的资源。

    auto n = make_shared<Node>();
    parent_node.push_back(n);
    

    顺便说一句,为什么或如何将节点作为指针而将 parent_node 作为值/引用?

    利用这个星期六做一些研究,我推荐GotW #89 或者如果由于任何原因你不能使用 C++11 使用 boost Boost

    【讨论】:

    • 抱歉,我的描述写错了。我的结构称为节点。在我的结构中,我有一个名为 children 的列表。因此,我保留了我的结构向下连接到的节点列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 2012-08-25
    • 2019-10-28
    • 2010-12-21
    • 2012-10-08
    • 2017-09-03
    • 2020-09-30
    相关资源
    最近更新 更多