C++中内存泄漏和智能指针

内存泄漏

含义

由于疏忽或错误导致程序未能释放已经不再使用的内存。并不是指内存在物理上的消失,而是在应用程序分配某段内存后,因为设计错误,而失去了对该段内存的控制,因而造成了内存泄漏。

危害

长期运行的程序出现内存泄漏,如操作系统、后台服务等,会导致响应越来越慢,最终卡死。

内存泄漏分类

堆内存泄漏(heap leak)
堆内存泄漏指的是通过malloc / calloc / realloc / new 等从堆中分配的一块内存,在使用完成以后,没有使用free / delete 删除。假设因为程序的设计错误导致这块内存没有被删掉,就会导致以后无法使用,就会造成堆内存泄漏。

系统资源泄漏
指程序使用系统分配的资源,如套接字、文件描述符、管道没有使用对应的函数释放,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。

避免内存泄漏方式

  1. 良好的编码规范,动态申请的内存记着要去释放。
  2. 采用RALL思想或者使用智能指针来管理资源。
  3. 出问题了使用内存泄漏检测工具。

内存泄漏与溢出区别

1. 内存泄漏(momory leak):
是指程序在申请新的内存空间后,没有释放已经申请的内存空间,后果也许会造成内存溢出。

2. 内存溢出(out of memory):
指程序申请内存时,没有足够的内存提供给申请者。内存不够用。

3. 二者的关系
内存泄漏最终会导致内存溢出。
内存溢出就是你要的内存空间超过了系统能给你分配的空间,系统无法满足你的要求,就会报内存溢出的错误。
内存泄漏是指向系统动态申请的内存,用完以后不归还,结果你申请的那块空间也不能再次使用了。
内存溢出比如说栈,当栈满的时候再进栈必定会内存溢出,叫上溢。当栈空的时候还要出栈叫下溢。
4. 内存溢出的原因及解决

原因
内存加载的数据量过于庞大,如一次从数据库取出过多数据。

代码中存在死循环或者循环过多重复的实体对象

使用第三方软件中的BUG

启动参数内存值设定的过小

解决
检查代码中是否有死循环或递归调用

检查是否有大循环重复产生新对象实体

检查对数据库查询中,是否有一次性获取全部数据。


智能指针

#include < memory>

 shared_ptr

#include < memory>
这里的指针主要指的是shared_ptr,是一种引用计数型智能指针。可以记录内存中有多少个智能指针被引用,新增一个引用计数+ 1,过期一个引用计数 - 1,当引用计数为 0 的时候 , 智能指针才会释放资源。

通过引用计数的方式实现多个shared_ptr对象之间的共享资源。
 

#include 
#include 

using namespace std;

class A
{
public:
    A(int count)
    {
        _nCount = count;
    }
    ~A(){}
    void Print()
    {
        cout<<"count:"<<_nCount<p(new A(10));//初始化 
    p->Print();
    return 0;
}

unique_ptr


独占式智能指针,不允许拷贝复制,不允许拷贝构造。

是线程安全的。由于只是在当前代码块范围内生效, 因此不涉及线程安全问题

weak_ptr


弱引用指针,用于观察shared_ptr或weak_ptr。用于解决循环引用 计数。

因为weak_ptr没有共享资源,它的构造函数不会引起智能指针引用计数的变化。
 

你可能感兴趣的:(c++,c++)