总结--内存 + 智能指针

在内存这块我们主要讨论一下几方面:

C语言内存(new 、delete)、智能指针、内存泄漏

 

 

 

C语言内存(new 、delete)

 

在现代c++中,应该尽量避免使用底层内存,而是只用现代结构,例如容器、智能指针。

mallo()、与new的区别

malloc只负责申请你所指定的内存大小。而new不仅会分配正确的内存大小,还会调用相应的对象的构造函数以构建对象。

free()和delete的区别

使用free()时不会调用对象的析构函数,使用delete会调用对象的析构函数。

new与new[ ]   和 delete与delete[ ]

new[ ] 是申请的一维数组,

delete[ ]释放的是一维数组。

重点是下面的情况。我正确申请了一个一位数组,可我却用delete释放,而没用delete[ ]释放会发生什么??

int *p = new int[10];
delete p;  // 会发生什么???

如同上述缩写,编译器不会报错。程序正常执行。但是为什么会这样???

p指向的是申请的10个int的首地址。delete释放的int[0],只将int[0] 运行了析构函数 ,其他9个并没有,如果不是int类型而是 对象,那会造成内存泄漏。所以要正常释放。

c++禁止使用realloc()函数,

 

我们常常接触到二维数组,现代c++尽量要求使用标准库替代。

 

智能指针:

智能指针可帮助管理动态分配的内存,避免内存泄漏。

unique_ptr 

唯一所有权,离开作用域或被重置时会释放所引用的内存,unique_ptr总将动态分配的内存的对象保存在栈中。例如:

void leak()
{
    Simple* p = new Simple;   // new
    p->go();     // 没有释放内存,导致内存泄漏
}

void leak()
{
    Simple* p = new Simple;   // new
    p->go();     // 
    delete p;      // 虽然加上了这句话,但是也有可能导致内存泄漏,原因是加入go()抛出异常,将永远不会调用delete,导致内存泄漏。
}

// 使用unique_ptr避免了所有问题

void leak()
{
    auto* p = make_unique<Simple>();   // make_unique() 函数
    p->go();     // j结束后自动释放p
}

 

用make_unique()创建unique_ptr

 

 

shared_ptr:

void doubleDelete
{
    Simple* p = new Simple;
    share_ptr<Simple> p1(p);   // 计数1
    share_ptr<Simple> p2(p);   // 计数2
}// 由于没有释放new,error

 

void doubleDelete
{
    auto* p = make_shared<Simple>();
    share_ptr<Simple> p1(p);   // 计数1
    share_ptr<Simple> p2(p);   // 计数2
}// ok

 

 

内存泄漏问题

在Windows下如果使用的是vc++,在创建MFC时,自动打开内存检测工具,要在其他项目中添加如下代码:

#define _CRTDBG_MAP_ALLOC
#include <cstdlib>
#include <crtdbg.h>

// 重新定义new运算符
#ifdef_DEBUG
    #ifndef DBG_NEW_new
        #define DBG_NEW_new (_NORMAL_BLOCK,_FILE_,_LINE_)
        #define new DBG_NEW
    #endif
#endif

// 最后要在main()函数最第一行终添加
_CrtSetDbgFlag(_VRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

 

在linux中可以通过Valgrind查找内存泄漏

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值