C++内存泄漏如何避免?四种智能指针全面总结

一 、C++的内存泄漏是什么  如何避免,new 和delete的用法

内存泄漏:申请一块内存后,没有释放掉。表现为程序运行时间越长内存占用越大,最终占用全部 内存,系统崩溃。---由程序员申请的内存  没有指针指向它 那这块内存就泄露了

new delete   

delete  :释放p指向的内存  不删除p   指针p依旧可以指向别的地方

删除p指针后可将p为nullptr空指针(C++11新特性)

二、共享指针 shared_ptr 如何帮你自动管理内存

共享指针 :记录有多少个共享指针指向这个内存 当为0时会自动释放--引用计数

如果裸指针和共享指针同时指向一个地方那么当计数为0时 共享指针依旧会释放该内存,裸指针再访问会有问题 所以应该避免混用

make_shared是一个模版  可接受 一个类型和参数  (推荐)

new

举例通过析构函数观察销毁情况

p.use_count()查看计数个数,p.reset() 释放空间 也可指向新的地址  全部释放后 调用析构函数

p.reset(q) //q为智能指针要指向的新对象

三、shared_ptr 补充知识点

1.可自定义销毁方式---关闭文件 断开网络等

2.别名    用来访问类的成员变量 

b具有 f指向内容Foo  bar 的管理权  ,如果b不被销毁则该内存不能被销毁

也就是说 当想要访问一个类的实例的成员属性时 使用此功能防止 这个实力被销毁无法访问属性

3.危险操作--使用共享指针避免使用 delete

4.额外内存开销--性能极为苛刻不合适

四、为什么你应该尽可能使用unique_ptr替换裸指针*

1.unique_ptr:

独占资源,同一时间只有一个智能指针可以指向该对象

unique_ptr 不像 shared_ptr 一样拥有标准库函数 make_shared 来创建一个 shared_ptr 实例。要想创建一个 unique_ptr,我们需要将一个new 操作符返回的指针传递给 unique_ptr 的构造函数。
std::make_unique 是 C++14 才有的特性。

// 示例:
int main()
{
    // 创建一个unique_ptr实例
    unique_ptr<int> pInt(new int(5));
    cout << *pInt;
}

unique指向对象被销毁时 其绑定资源会自动释放 不需要手动delete

2.unique 相对裸指针的好处

当p->foo() 出现异常时  delete不会被执行 会造成内存泄漏

使用unique——ptr 资源一定会被释放

3.获得裸指针

依旧可通过 ->get获得裸指针

4.释放资源

直接释放资源     将up指向nullptr

释放资源指向新的内存 将up指向Ball实例

可使用release解绑

5.不支持普通拷贝

不可复制控制权但是可以转移

release转移

move转移

6.new delete 

默认情况下使用new delete 来分配和释放内存  

均可自定义替换  比shared_ptr更复杂  因为 unique_ptr绑定发生在编译期  shared 在运行时绑定

五、如何在函数间传递unique_ptr?

由于不能复制 但是函数在传值的时候需要复制  因此需要特别注意

编译会出错

1.传递

避免一,传递*up up 是指针  而*up为指针指向内容

传递 *up,实际上传递的是指向对象的原始指针,而不是 unique_ptr 对象本身。这意味着在函数内部,你只能访问对象,但不能管理其所有权。unique_ptr 仍然在调用函数结束后拥有对象的所有权

避免二,使用up.get()获取裸指针进行传递 

2.unique_ptr传递 

move  转移指针的控制权

move(up) 是用来将对象从一个地方移动到另一个地方的函数 这里将up移动到了pass_up函数中,意味着 up的所有权被转移到了函数的参数‘unique_ptr<int> up’中

unique_ptr作为返回值

六、weak_ptr 是什么,为什么要用它?

1.weak_ptr特性

是shared_ptr的伴侣 是一个观察者 对资源的引用时非拥有似的 没有资源的管理权限   

不能进行资源的释放  访问时需要创建一个临时的 shared指针   可以检查资源是否存在

2.为什么需要需要weak_ptr

shared_ptr会发生环形依赖--循环引用 计数无法记为0 无法释放

        1.weak_ptr使用时需要配合shared_ptr使用如main函数前三行

        2.weak_ptr想要访问资源需要使用 .lock()函数使用  

                若访问内容未被释放,会返回一个shared_ptr

                若访问内容已被释放,会返回一个nullptr

        因此可以判断资源是否存在;

 推荐30分钟讲明白现代C++最重要的特性之一:智能指针_哔哩哔哩_bilibili

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现无内存泄漏的链表可以使用智能指针来管理链表节点的内存,这样可以避免手动释放内存时出现的错误和忘记释放内存的问题。 下面是一个使用智能指针实现的单向链表的示例代码: ```c++ #include <memory> template <typename T> struct Node { T data; std::unique_ptr<Node<T>> next; Node(T data) : data(data), next(nullptr) {} }; template <typename T> class LinkedList { public: LinkedList() : head(nullptr), size(0) {} void pushFront(T data) { std::unique_ptr<Node<T>> newNode = std::make_unique<Node<T>>(data); newNode->next = std::move(head); head = std::move(newNode); size++; } void popFront() { if (head == nullptr) { return; } head = std::move(head->next); size--; } int getSize() const { return size; } private: std::unique_ptr<Node<T>> head; int size; }; ``` 在这个示例中,我们使用了 `std::unique_ptr<Node<T>>` 来管理链表节点的内存。在 `pushFront` 方法中,我们创建一个新的节点,并将其指针赋值给 `std::unique_ptr<Node<T>> newNode`。然后,我们将 `head` 的值移动到 `newNode->next` 中,将 `newNode` 移动到 `head` 中。这样,`newNode` 的所有权就被转移到了 `head` 中,`newNode` 的内存会在 `pushFront` 方法结束时自动释放。 在 `popFront` 方法中,我们将 `head` 的值移动到其下一个节点,并通过这种方式释放了 `head` 的内存。 使用智能指针来管理链表节点的内存可以极大地简化代码和减少错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值