我有一个名为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;
}
这怎么会泄漏内存?他们不是指同一件事吗?它们应该相同,对吧?
答案 0 :(得分:1)
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 *&x = my_array[0];
或现代C ++,auto& x = my_array[0];
。
答案 1 :(得分:1)
您误解了指针的工作方式。指针是变量,就像其他变量一样,它们的值是一个内存地址。没事也没事。
此行:
Node* x = my_array[0];
将地址从my_array[0]
复制到名为x
的新变量。虽然地址相同,但是x
和my_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。这是极好的且简单的解释。