В этих строках кода C ++:
int * p = new int(33);
delete(p);
*p = 13;
cout << *p << endl;
Выход 13;
P сначала указывает на адрес в куче, затем я использую ключевое слово delete, чтобы освободить назначенный адрес памяти p, но все же могу присвоить адресу памяти значение 23; Это тот же адрес в куче, на который p указал после «int * p = new int (33)», или p указывает на адрес в стеке после использования delete (p)?
Удаление p
сигнализирует тому, кто управляет памятью (ОС), что базовое пространство теперь свободно перераспределяется кем-то другим для собственного использования. p
однако он все еще указывает на то же место в памяти и может быть разыменован для получения значения того, что находится в этой памяти — обратите внимание, что, поскольку эта память теперь может использоваться кем-то другим, базовые биты могут отличаться от того, что было раньше.
Это все еще указывает на тот же адрес (Вы можете сказать, напечатав адрес). Вы иногда будете видеть, как люди назначают NULL
или же nullptr
или же 0
на указатель после освобождения памяти, чтобы убедиться, что они не пытаются разыменовать освобожденную память, потому что ей не присваивается нулевое значение для них. Это позволяет им иметь такой код:
if (p != nullptr)
//do something with p, it hasn't been freed and set to nullptr
Это трудно сделать, если он не установлен в нуль при освобождении, но учтите, что умный указатель обеспечивает более безопасную и последовательную альтернативу вышеприведенному.
Причина, по которой вы получаете правильный вывод неопределенное поведение. Это может разбиться, может взорваться, или это может сработать. Я думаю, что он решил работать.
Да, он все еще указывает на кучу, но это место в памяти не является стабильным. ОС может вернуть его в любое время, поэтому значение в этом месте памяти не обязательно будет таким, как вы его установили.
Также, насколько я знаю, все динамическое распределение памяти происходит в куче, а не в стеке. Стек зарезервирован для параметров и локальных переменных.