A* a = new A();
A* b = a;
a = NULL;
После этого b
по-прежнему указывает на объект, выделенный в первой строке. a
теперь ни на что не указывает. Вы по-прежнему можете «использовать» объект с помощью указателя b
и удалить объект с помощью delete b;
.
Вы можете delete a;
здесь - это не будет иметь никакого эффекта (поскольку a
равно NULL), но это безопасно и не приведет к неопределенному поведению.
A* a = new A();
A* b = a;
delete a;
После delete
объект, на который a
и b
использовали для указания, больше не существует. Следовательно, a
и b
больше не являются действительными указателями, и вы не можете делать с ними ничего, что использует их значение. В частности, попытка разыменования любого указателя приведет к неопределенному поведению. (Но вы можете использовать переменные повторно, если вы сделаете так, чтобы они указывали на действительный объект.)
A* a = new A();
a = NULL;
Вы только что слили объект, созданный в первой строке. a
больше не указывает ни на что, и у вас нет дескриптора этого объекта, поэтому вы не можете его удалить. Итак, это старая утечка памяти.
(Как и в первом случае, вы можете delete a;
после строки a = NULL;
, но это не будет иметь никакого эффекта, память все еще протекает.)