2012-09-29 60 views
0

可能重复:
how to safely delete multiple pointers如何删除超过1个指针指向同一个地址

如下面的代码:

#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; 
} 

pq。当我删除qq = NULL时,p仍然指向旧地址。 有没有人有办法让p自动指向qNULL? 因为如果在程序中有很多指向相同地址的指针,我们不能让它们指向NULL它会带来问题。

+0

好吧,指向变量的指针只是指向变量的两个指针,所以你必须手动完成。或者尝试将它作为一个数组,在那里你有p [2],然后有两个单独的poiinters,然后通过遍历数组来删除它们。 – Annabelle

+1

因此,与std :: shared_ptr不同,最后一个引用最终释放货物,所以您希望对象(和本例中的int)知道对它的所有引用,并清除它们* all * *其中任何*都是free'd ? – WhozCraig

+0

不能把'p'作为参考吗? http://ideone.com/ahFmH – chris

回答

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

C++程序的一般建议是避免基本的指针,正是为了避免你遇到的问题。相反,使用的语言(或更精确的标准库)的方法来处理指针:

1使用的容器,如std::vector,而不是指向堆上

2利用分配(大块)内存std::unique_ptrstd::shared_ptr(和std::weak_ptr)来管理在堆上分配的对象。这只适用于C++ 11及其移动语义,请参阅标准头文件。

优点:自动解除分配而不留下悬挂指针;异常安全(抛出异常和堆栈倒回不会泄漏内存)。