Когда вы delete
что-то, вы не уничтожаете память, вы просто помечаете это как неиспользованное. (Вы также можете запустить код очистки, содержащийся в деструкторах, но это уже другая история.) Сама память, то есть физические биты и байты, остаются на своих местах, как и раньше.
Таким образом, когда вы delete
указываете, указатель по-прежнему будет указывать на те же байты в физической памяти после факта , но вам больше не разрешено их использовать . Если вы это сделаете, все может случиться. Это относится даже к самому указателю: любой указатель, указывающий на delete
d памяти, больше не должен касаться, он сразу же становится недействительным.
Если вы используете указатель после того, как он был delete
d, он может работать правильно. Или вы можете потерпеть крах. Или вы можете получить доступ к другому объекту памяти, который был создан с использованием тех же физических байтов памяти. Вы просто не знаете, что на самом деле произойдет .
Таким образом, ваша первоначальная идея верна: delete
нужен только один из двух указателей, другой не следует трогать после факта:
int* k;
k = new int(5);
int* d = k;
cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;
delete d;
// cout<<"d's : "<<d<<endl; //Undefined behavior, the pointer is invalid now
// cout<<"k's : "<<k<<endl; //Undefined behavior, k is invalid as well
// delete k; //Undefined behavior, k is invalid