Установка переменной, равной переменной, равной nullptr - PullRequest
2 голосов
/ 05 мая 2019

У меня есть массив с именем 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;
}

как это утечка памяти? Разве они не указывают на одно и то же? Они должны быть одинаковыми, верно?

Ответы [ 2 ]

1 голос
/ 05 мая 2019

Вы неправильно поняли, как работают указатели. Указатели являются переменными, как и любые другие, и их значение - адрес памяти Не больше и не меньше.

Эта строка:

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. Так что второй может тоже не протечь.

Я настоятельно рекомендую вам посмотреть POINTERS от TheCherno. Это отличное и простое объяснение.

1 голос
/ 05 мая 2019

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];.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...