c++智能指针内存泄漏的问题

参考文档:https://blog.csdn.net/jcq521045349/article/details/88957222
在这里插入图片描述
弱引用的智能指针weak_ptr是用来监视shared_ptr的,不会使引用计数加一,它不管理shared_ptr内部的指针,主要是为了监视shared_ptr的生命周期,更像是shared_ptr的一个助手。
weak_ptr没有重载运算符*和->,因为它不共享指针,不能操作资源,主要是为了通过shared_ptr获得资源的监测权,它的构造不会增加引用计数,它的析构不会减少引用计数,纯粹只是作为一个旁观者来监视shared_ptr中关离得资源是否存在。
weak_ptr还可以用来返回this指针和解决循环引用的问题。weak_ptr 的一个重要用途是“打破循环引用”,即解决 shared_ptr (引用计数)在循环引用中的“无能”。

使用弱引用wak_ptr来解决智能指针内存泄漏的例子

template <class T>
class WeakedPtr;

template<class T>
class SharePtr
{
public:
    friend class WeakedPtr<T>;
    SharePtr(T* ptr =  NULL) :_ptr(ptr), _refCount(new int(1))
    {}
    ~SharePtr()
    {
        if (--(*_refCount) == 0)
        {

            delete _ptr;
            delete _refCount;
        }
    }
    //s1(s2)
    SharePtr(const SharePtr<T>& sp) :_ptr(sp._ptr), _refCount(sp._refCount)
    {
        (*_refCount)++;
    }
    //sp1 = sp2
    SharePtr<T>& operator=(SharePtr<T>& sp)
    {
            if (_ptr != sp._ptr)
            {
                if (--(*_refCount) == 0)
                {
                    delete _ptr;
                    delete _refCount;
                }
                _ptr = sp._ptr;
                _refCount = sp._refCount;
                (*_refCount)++;
            }
        return *this;
    }
    //为了像指针一样才进行*\->的重载
    //->的重载
    T* operator->()
    {
        return _ptr;
    }
    //*的重载
    T& operator*()
    {
        return *_ptr;
    }
    //查看引用计数的多少
    int UseCount()
    {
        return *_refCount;
    }
private:
    T* _ptr;
    int* _refCount;//一块空间有一个指针
};

//解决了循环引用问题
template <class T>
class WeakedPtr
{
public:
    WeakedPtr() :_ptr(NULL)
    {}
    WeakedPtr(const SharePtr<T>& sp)
        :_ptr(sp._ptr)
    {}

    WeakedPtr<T>& operator=(const SharePtr<T>&sp)
    {
        _ptr = sp._ptr;
        return *this;
    }
    T& operator* ()
    {
        return *_ptr;
    }
    T* operator->()
    {
        return _ptr;
    }
private:
    T* _ptr;
};


struct  ListNode
{
    int _data;
    WeakedPtr<ListNode> _next;
    WeakedPtr<ListNode> _prev;

    ~ListNode()
    {
        cout << "~ListNode" << endl;
    }
};
void testSharePtr()
{
    //SharePtr<int> sp1(new int(1));
    //SharePtr<int> sp2(sp1);

    SharePtr<ListNode> cur(new ListNode);
    SharePtr<ListNode> next(new ListNode);

    cout << cur.UseCount() << endl;
    cout << next.UseCount() << endl;
}

C++11智能指针内存泄漏查找方法
可以在XCODE中先查看是否存在内存泄漏,如果有就一步一步查。
1.析构函数打断点,查看退出场景时某类的析构函数是否调用。
2.强引用的地方查看是否有循环引用。如果有,使用weak_ptr
如可以,最好保证只有一个最必要的地方对其持有强引用并管理。
3.查看基类是否是虚析构函数。 如果不是就改正。
4.lambda表达式[pointer]中的引用指针是永久持有,所以不要随意的添加变量。
这里有特殊情况,如果是异步操作,局部变量的智能指针是没有被引用的,所以在异步的回调中智能指针已被释放,所以请注意保证指针的引用计数。

原文地址:https://blog.csdn.net/qq_36474990/article/details/78748895

猜你喜欢

转载自blog.csdn.net/qq_23350817/article/details/89916768
今日推荐