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


相关文章
|
1月前
|
存储 程序员 编译器
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
|
2月前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
112 1
|
3月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
267 13
|
3月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
90 11
|
3月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
3月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
3月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
3月前
|
存储 缓存 C语言
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
83 3
|
3月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
249 4
|
4月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。