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

时间:2015-01-12 05:16:02

标签: c++ pointers c++11 crash unique-ptr

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

  

Trees.exe中0x00DE5CC3处的未处理异常:0xC0000005:Access   违规阅读地点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;
}

1 个答案:

答案 0 :(得分:9)

unique_ptr<node> (r->left) = newNode(2);

这并不是你认为它做的事情(虽然很难准确地说出你想象中的)。这就是:

  1. 构建临时unique_ptr,使用r->left(当前为nullptr)初始化。

  2. 此临时unique_ptr已重新分配,现在保留newNode(2)返回的值。

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

  4. 最后,这条线是精心制作的无操作。它分配一块内存,然后立即释放它。 r->left未以任何方式进行修改,仍为nullptr

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


    如果您希望获得unique_ptr之外的任何里程,请node成员unique_ptr,如

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