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->get()
而不是 it->release()
,则会收到错误消息
free(): invalid pointer
我想在某个时候重用孩子们,我认为it->release()
会破坏指针,因此之后它就无法使用,但似乎指针仍然存在,这让我感到困惑。
此外,我认为it->get()
是可行的方法,因为我只想获取值而不破坏指针。我在想调用it->get()
时可能会出现一些内存泄漏类型的错误,这就是为什么我在使用完每个孩子之后尝试对每个孩子调用it->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
的唯一原因以及它存在的唯一原因是new
ed 对象自动获得delete
d,以防止内存泄漏。这就是它的全部使命宣言。
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() 时指针无效的主要内容,如果未能解决你的问题,请参考以下文章