为什么代码在使用 unique_ptr 时崩溃,原始指针工作正常?

Why code is crashing while using unique_ptr, raw pointer works fine?

这是我为树节点赋值的代码。我能够很好地分配树的左右 child。但是当我尝试使用 root 的 left->left child 时,它给了我访问冲突错误。

Unhandled exception at 0x00DE5CC3 in Trees.exe: 0xC0000005: Access violation reading location 0x00000004.

在行中确实出错,unique_ptr<node> (r->left->left) = newNode(4);

我正在使用 unique_ptr,如果我使用原始指针,一切都会按预期工作。

以下是我的代码,

using std::cout;
using std::endl;
using std::unique_ptr;


struct node
{
    int data;
    node * left;
    node * right;
};

unique_ptr<node> newNode (int i)
{
    unique_ptr<node> n (new node);
    n->data = i;
    n->left = nullptr;
    n->right = nullptr;

    return n;
}

int main(int argc, char* argv[])
{
    unique_ptr<node> r = newNode(1); 
    unique_ptr<node> (r->left) = newNode(2);
    unique_ptr<node> (r->right) = newNode(3);
    unique_ptr<node> (r->left->left) = newNode(4);//this line craches 
    unique_ptr<node> (r->left->right) = newNode(5);
    return 0;
}
unique_ptr<node> (r->left) = newNode(2);

这并不像您想象的那样(尽管很难准确地说 您想象的是什么)。这是发生了什么:

  1. 构造了一个临时的unique_ptr,初始化为r->left(当前为nullptr)的值。

  2. 这个临时 unique_ptr 被重新分配,现在保存 newNode(2) 返回的值。

  3. 分号处,临时销毁;它的析构函数删除它持有的指针。

最后,这一行是精心设计的空操作。它分配一块内存,然后立即释放它。 r->left 没有任何修改,仍然是 nullptr.

然后,r->left->left 崩溃,因为您正试图取消引用空指针。


如果您希望从 unique_ptr 中获得任何好处,请让 node 成为会员 unique_ptr,如

struct node
{
    int data;
    unique_ptr<node> left;
    unique_ptr<node> right;
};