free():在 unique_ptr 上使用 get() 而不是 release() 时指针无效

Posted

技术标签:

【中文标题】free():在 unique_ptr 上使用 get() 而不是 release() 时指针无效【英文标题】:free(): invalid pointer when using get() instead of release() on unique_ptr 【发布时间】:2021-12-30 13:40:59 【问题描述】:

我有以下程序:

#include <list>
#include <stack>  
#include <memory>

struct ChildNode ;

struct value_node_ptr : public std::unique_ptr<ChildNode> 
    using std::unique_ptr<ChildNode>::unique_ptr;
    using std::unique_ptr<ChildNode>::reset;
;

struct Node 
    std::list<value_node_ptr> children;
    void addChild(ChildNode* child)
        children.emplace_back(child);
    
;

void iterateChildren(Node* node)
    for(auto it=node->children.begin(); it != node->children.end(); ++it)
        auto child = it->release();
        //do stuff with child
    


int main() 
    ChildNode child;
    Node node;
    node.addChild(&child);

    std::stack<Node*> nodes;
    nodes.push(&node);
    iterateChildren(nodes.top());

    nodes.pop();

这很好用。但如果我在 iterateChildren 函数中使用 it-&gt;get() 而不是 it-&gt;release(),则会收到错误消息

free(): invalid pointer

我想在某个时候重用孩子们,我认为it-&gt;release() 会破坏指针,因此之后它就无法使用,但似乎指针仍然存在,这让我感到困惑。

此外,我认为it-&gt;get() 是可行的方法,因为我只想获取值而不破坏指针。我在想调用it-&gt;get() 时可能会出现一些内存泄漏类型的错误,这就是为什么我在使用完每个孩子之后尝试对每个孩子调用it-&gt;reset(),但这也没有解决错误。

谁能解释我这种行为以及我应该使用哪种方法?

【问题讨论】:

您正在使用unique_ptr 作为指向自动存储 ChildNode 对象的指针。 这能回答你的问题吗? Using of Smart Pointers on objects with automatic storage duration 【参考方案1】:
ChildNode child;
Node node;
node.addChild(&child);

addChild() 从这个传入的指针构造一个std::unique_ptr

拥有std::unique_ptr 的唯一原因以及它存在的唯一原因是newed 对象自动获得deleted,以防止内存泄漏。这就是它的全部使命宣言。

std::unique_ptr(和std::shared_ptr 也是)不适用于指向在自动作用域中声明的对象的指针,并且在自动作用域结束时将自动销毁。如果您不使用new 创建对象,那么绝对没有理由使用std::unique_ptr。除了产生此类错误和内存错误之外,它不会完成任何事情。

您要么需要删除对std::unique_ptr 的所有使用(因为它没有任何作用,只会在此处产生问题),或者在将其所有权分配给std::unique_ptr 之前使用new 创建所有对象。

【讨论】:

另外,不要使用new,而是使用std::make_unique。 (unique_ptr 还有另一个用例,它可以有一个客户删除器,用于术后清理。但这与 OP 的用例无关。)

以上是关于free():在 unique_ptr 上使用 get() 而不是 release() 时指针无效的主要内容,如果未能解决你的问题,请参考以下文章

C ++ unique_ptr和map

如何在结构上使用 std::unique_ptr?

std::unique_ptr::reset 重载问题

第九篇:top命令free命令

linux系统free查看内存,发现可用物理内存很少,但是查看进程却发现没进程占用大内存

oracle查看表空间使用情况