【问题标题】:Setting a variable equal to a variable that is equal to nullptr将变量设置为等于 nullptr 的变量
【发布时间】:2019-05-05 07:11:57
【问题描述】:

我有一个名为my_array 的链表数组。

Node* x = my_array[0];
if (head == nullptr)
{
    my_array[0] = new Node;
}

为什么这个可以正常工作,但是

Node* x = my_array[0];
if (head == nullptr)
{
    x = new Node;
}

这个怎么会泄露内存?他们不是指向同一个东西吗?应该是一样的吧?

【问题讨论】:

  • X 是一个单独的变量,您对其进行了初始化。尝试使用Node *&x 将其设为别名

标签: c++ pointers linked-list


【解决方案1】:

您误解了指针的工作原理。指针和其他变量一样是变量,它们的值是内存地址。不多也不少。

这一行:

Node* x = my_array[0];

将地址从my_array[0] 复制到一个名为x 的新变量中。虽然地址相同,但xmy_array[0] 不是一回事。它们是两个不同的变量,拥有相同的地址。

这一行:

my_array[0] = new Node;

my_array[0] 的地址重新分配给分配的Node 对象的新地址。它会覆盖my_array[0] 中的旧地址,从而导致内存泄漏,因为该地址(以及其中的对象)从未被释放。但是,您仍然在 x 中拥有它,因此您仍然可以释放它并防止泄漏。

这一行:

x = new Node;

本质上做同样的事情,但会覆盖x 中存储的地址。不过这可能没问题,因为原始地址仍在my_array[0] 中(请记住x 只是该地址的副本)并且可能稍后会被释放。而且您也可以在x 中释放新地址。所以第二个也可能不会泄漏。

我强烈建议您观看 TheCherno 的 POINTERS。这是一个优秀而简单的解释。

【讨论】:

    【解决方案2】:

    x 本身是一个变量,它不是my_array[0] 的别名。更改x 只会影响x 的值。

    例子:

    int zero = 0;
    int one = 1;
    int* arr[] = {&zero};
    int* x = arr[0];
    x = &one;
    std::cout << "*arr[0] = " << *arr[0] << '\n'
      << "*x = " << *x;
    

    输出:

    *arr[0] = 0
    *x = 1
    

    如您所见,x 指向的内容已更改,但数组不受影响。现在,如果你想要一个别名,你应该使用一个引用:

    int* arr[] = {&zero};
    int*& x = arr[0];
    x = &one; // note the &
    std::cout << "*arr[0] = " << *arr[0] << '\n'
      << "*x = " << *x;
    

    输出:

    *arr[0] = 1
    *x = 1
    

    意味着您应该使用Node *&amp;x = my_array[0]; 或现代C++,auto&amp; x = my_array[0];

    【讨论】:

      猜你喜欢
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多