В отличие от классов, при удалении объектов встроенного типа не происходит ничего. В частности, когда указатель выходит из области видимости, с объектом, на который он указывает, ничего не происходит. Если этот указатель указывает на динамическую память, она не освобождается автоматически.
В этом примере указатель p был единственным указателем на область памяти, зарезервированную функцией factory(). По завершении функции use_factory() у программы больше нет никакого способа освободить эту память. Согласно общей логике программирования, следует исправить эту ошибку и напомнить о необходимости освобождения памяти в функции use_factory():
void use_factory(Т arg) {
Foo *p = factory(arg);
//
delete p; //
//
}
Если созданный функцией use_factory() объект должен использовать другой код, то эту функцию следует изменить так, чтобы она возвращала указатель на зарезервированную ею память:
Foo* use_factory(Т arg) {
Foo *p = factory(arg);
//
return p; //
}
Есть три общеизвестных проблемы, связанных с использованием операторов new и delete при управлении динамической памятью:
1. Память забыли освободить. Когда динамическая память не освобождается, это называется "утечка памяти", поскольку она уже не возвращается в пул динамической памяти. Проверка утечек памяти очень трудна, поскольку она обычно не проявляется, пока приложение, проработав достаточно долго, фактически не исчерпает память.
2. Объект использован после удаления. Иногда эта ошибка обнаруживается при создании нулевого указателя после удаления.
3. Повторное освобождение той же памяти. Эта ошибка может произойти в случае, когда два указателя указывают на тот же динамически созданный объект. Если оператор delete применен к одному из указателей, то память объекта возвращается в пул динамической памяти. Если впоследствии применить оператор delete ко второму указателю, то динамическая память может быть нарушена.
Допустить эти ошибки значительно проще, чем потом найти и исправить.
Когда указатель удаляется, он становится недопустимым. Но, даже став недопустимым, на многих машинах он продолжает содержать адрес уже освобожденной области динамической памяти. После освобождения области памяти указатель на нее становится
Потерянным указателям присущи все проблемы неинициализированных указателей (см. раздел 2.3.2). Проблем с потерянными указателями можно избежать, освободив связанную с ними память непосредственно перед выходом из области видимости самого указателя. Так не появится шанса использовать указатель уже после того, как связанная с ним память будет освобождена. Если указатель необходимо сохранить, то после применения оператора delete ему можно присвоить значение nullptr. Это непосредственно свидетельствует о том, что указатель не указывает на объект.