Возможный дубликат:
как безопасно удалить несколько указателей
Как код ниже:
#include <iostream>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
int *p, *q;
q = new int;
p = q;
delete q;
q = NULL;
cout << p << " " <<q << endl;
return 0;
}
p
указать на q
, Когда я удаляю q
а также q
знак равно NULL
, p
по-прежнему указывает на старый адрес.
У кого-нибудь есть какой-нибудь способ сделать p
указать на q
NULL
автоматически?
Потому что, если в программе есть много указателей, которые указывают на один и тот же адрес, и мы не можем заставить их указывать на NULL
это принесет проблемы.
Существует тип умного указателя, который может сделать эту работу. С этим кодом могут возникнуть проблемы с безопасностью потоков (на самом деле я гарантирую, что так будет).
template <class T>
class DoublyLinkedSmartPointer
{
public:
DoublyLinkedSmartPointer(const DoublyLinkedSmartPointer &other);
DoublyLinkedSmartPointer& operator=(const DoublyLinkedSmartPointer& other);
virtual ~DoubleLinkedSmartPointer();
T * operator*();
const T* operator*() const;
void freeAll();
private:
DoublyLinkedSmartPointer *next, *previous;
T * data;
}
Основная идея заключается в том, что всякий раз, когда копия создается из интеллектуального указателя, вы добавляете ее в
список с использованием умного указателя, используемого для его инициализации. И когда вы удаляете указатель, вы
освободить его из списка.
Теперь хитрый бит, так как каждый указатель знает каждый другой указатель, вы можете просмотреть список из любой точки и установить для данных значение NULL в каждом узле.
Хорошо, вот как ты мог это сделать. Но что более важно, не делай этого. Вы почти наверняка создадите код, который сложно поддерживать и практически невозможно отладить. Лучшие стратегии управления памятью самые простые.
Общий совет для программ на C ++ — избегать элементарных указателей, чтобы избежать проблем, которые у вас возникают. Вместо этого используйте методы языка (или, точнее, его стандартной библиотеки) для работы с указателями:
1 использовать контейнеры, такие как std::vector
вместо указателей на (куски) памяти, выделенной в куче
2 использования std::unique_ptr
а также std::shared_ptr
(а также std::weak_ptr
) управлять объектами, расположенными в куче. Это работает правильно только в C ++ 11 с его семантикой перемещения, см. Стандартный заголовок.
Преимущества: автоматическое удаление, не оставляя висячих указателей; безопасность исключений (создание исключения и перемотка стека не приводит к утечке памяти).