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

Pra*_*ari 0 c++ crash pointers unique-ptr c++11

这是我的代码,我将值分配给树的节点.我可以很好地分配到树的左右孩子.但是当我尝试使用root的left-> left child时,它会给我访问冲突错误.

Trees.exe中0x00DE5CC3处的未处理异常:0xC0000005:访问冲突读取位置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;
}
Run Code Online (Sandbox Code Playgroud)

Igo*_*nik 9

unique_ptr<node> (r->left) = newNode(2);
Run Code Online (Sandbox Code Playgroud)

这并不像你认为的那样(尽管很难准确地说你想象的这样做).这是发生的事情:

  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;
};
Run Code Online (Sandbox Code Playgroud)