Что происходит после удаления ptr C++

Я пытаюсь удалить PTR, используя следующий пример кода:

int* data = new int(1);

int* p = NULL; 

p = data;

*p = 3;

delete p;

// Prints 3
cout << *p << endl;

//Prints 3    
cout << *data << endl;

Последние две строки кода печатают 3, и мой вопрос: что удаляется после delete p? Судя по тому, что он выводит из последних двух строк кода, кажется, что ничего не удалено 0.0~~

Кто-нибудь, пожалуйста, объясните мне это. Спасибо всем заранее.


person Mocha    schedule 13.02.2019    source источник
comment
То, что происходит, не определено Стандартом. Что касается C++, адрес недействителен и не должен использоваться. Что произойдет, если вы все равно его используете, никто не знает.   -  person user4581301    schedule 13.02.2019
comment
Обычно происходит то, что кусок памяти, на который указывает указатель, добавляется обратно в список доступной памяти процесса, что означает, что он может быть передан другому коду в вашем процессе через будущий вызов new/malloc()/etc. Небезопасно читать или записывать эту память после вызова удаления (как потому, что какой-то другой поток может уже повторно использовать ее, так и более формально, потому что это вызывает неопределенное поведение, что означает, что компилятор может предположить, что вы никогда этого не сделаете, и, следовательно, может с радостью позволить происходить странным/неприятным/таинственным вещам, если вы это сделаете)   -  person Jeremy Friesner    schedule 13.02.2019
comment
Как только вы удалите указатель, его использование для чего угодно приведет к носовым демонам. Я слышал, что это может быть довольно болезненным. Но некоторые люди даже не замечают их, пока однажды не разозлятся без всякой видимой причины и не проткнут вам внутреннюю часть носа своими маленькими вилками.   -  person Omnifarious    schedule 13.02.2019


Ответы (2)


Разыменование указателя после того, как у вас есть deleted объект, является причиной неопределенного поведения. Не рассчитывайте на какое-либо предсказуемое поведение и избегайте его.

Исключительное чтение висячих указателей, возникающих из-за другого угла и неопределенного поведения: scope/6445794#6445794">Можно ли получить доступ к памяти локальной переменной за пределами ее области?

person R Sahu    schedule 13.02.2019
comment
Тогда и p, и data становятся непредсказуемыми, или только сам "p" становится непредсказуемым??? Какую дозу это значит, став un-predictable or predictable??? - person Mocha; 13.02.2019
comment
@Mocha, вы не должны разыменовывать ни одну из этих переменных. - person R Sahu; 13.02.2019
comment
Затем он просто распечатает адреса памяти этих указателей~ - person Mocha; 13.02.2019
comment
@Mocha, я не следил за этим комментарием. - person R Sahu; 13.02.2019
comment
хорошо, я вижу. так как он будет помечен как неиспользуемая память. люди не будут пытаться использовать его после удаления. Тогда могу ли я сказать, что адрес памяти p помечен как неиспользуемый, когда я delete p. Адрес памяти data не помечается как неиспользуемый. - person Mocha; 13.02.2019
comment
@Mocha, не имеет значения, используете ли вы delete p; или delete data;, поскольку оба указывают на один и тот же объект. Независимо от того, какой из них вы используете, p и data становятся оборванными указателями. Разыменование любого из них является причиной неопределенного поведения. Ничто не помечено как неиспользованное. Как разработчик, вам придется следить за тем, что вы делаете с динамически выделяемой памятью, и убедиться, что вы не разыменовываете какие-либо висячие указатели. - person R Sahu; 13.02.2019

То, что происходит, не определено Стандартом. Что касается C++, адрес недействителен и не должен использоваться. Что произойдет, если вы все равно его используете, никто не знает.

На практике эта память обычно находится там до тех пор, пока она не понадобится кому-то еще. Все, что вы сделали, это сказали: «Мне это больше не нужно». Вы все еще можете получить к нему доступ некоторое время спустя, что приведет к очень плохим предположениям о пригодности вашего кода, но его можно вернуть и переназначить в любое время.

Если процессу нужна память для чего-то другого, возможно, он получит то, на что указал data. В этом случае использование data может привести к повреждению памяти, используемой другой частью вашей программы. Это действительно плохая сцена, потому что трудно отследить, что на самом деле произошло, когда что-то, совершенно не связанное с ошибкой, приводит к сбою программы.

Если другому процессу требуется память, возможно, базовая система забирает память и передает ее другому процессу. На современном ПК доступ к data после того, как память была передана другому процессу, будет фатальным.

person user4581301    schedule 13.02.2019