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

简介: 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


相关文章
|
2月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
2月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
12天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
60 12
|
10天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
21天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
47 4
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
2月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
125 21
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
41 0
【C++打怪之路Lv6】-- 内存管理