如下面的代码:
#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
它会带来问题。
答案 0 :(得分:4)
有一种智能指针可以完成这项工作。使用此代码可能存在线程安全问题(事实上我保证会有)。
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。
好的,这就是你如何做到的。但更重要的是,不要这样做。您几乎肯定会创建难以维护的代码,几乎无法调试。最好的内存管理策略是最简单的。
答案 1 :(得分:1)
C ++程序的一般建议是避免使用基本指针,正是为了避免您遇到的问题。相反,使用语言(或更准确地说是其标准库)的方法来处理指针:
1使用容器,例如std::vector
,而不是指向堆上分配的(块)内存
2使用std::unique_ptr
和std::shared_ptr
(以及std::weak_ptr
)来管理堆上分配的对象。这仅适用于带有移动语义的C ++ 11,请参阅标准头文件。
优点:自动解除分配而不留下悬空指针;异常安全(抛出异常和堆栈倒带不会泄漏内存)。