概述
在内存这块我们主要讨论一下几方面:
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查找内存泄漏
最后
以上就是独特抽屉为你收集整理的总结--内存 + 智能指针的全部内容,希望文章能够帮你解决总结--内存 + 智能指针所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复