内存分布
程序内存区域划分:
1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
创建共享共享内存,做进程间通信。
3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
4. 数据段--存储全局数据和静态数据。
5. 代码段--可执行的代码/只读常量。
c/c++动态内存管理方式
c
malloc/realloc/calloc/free
c++(new/delete)
new/delete操作内置类型
C语言内存管理方式在C++中可以继续使用(c++兼容c语言),但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用
new[]和delete[],注意:匹配起来使用。重要的事情说三遍:
匹配使用!!!匹配使用!!!匹配使用!!!
使用new动态申请内存,不能忘记使用delete释放,因为new出来的空间不会随着函数生命周期结束而自动释放,如果没有手动释放,ptr,ptr1,ptr2会消失,这几块地址无人访问,所以就会变成一块孤岛,无法使用,从而形成内存泄漏,c++最经典的bug
如果使用new
时分配了多块内存空间,而在释放内存时使用了delete
而没有带[]
,会导致内存泄漏。在这种情况下,只有第一个内存块会被正确释放,而后续的内存块将被忽略,从而导致内存泄漏问题。
同时也记住不能多次delete一块空间可能无事发生,也可能产生严重的后果,这是未知的,也不能使用free代替delete
所以
匹配使用!!!匹配使用!!!匹配使用!!!
为什么???
new申请多个空间时,会多申请一个空间存放申请空间个数,就比如A[10],会在申请空间前面再申请一个空间存放10,而指针则指向的是多申请空间的后面,申请空间的前面,所以delete[10]会在调用时向前退回空间,保证多申请的空间与申请的空间全部释放
new/delete操作自定义类型
在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与
free不会。
operator new 与 operator delete
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是
系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过
operator delete全局函数来释放空间。
operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。
那么为什么c++中要使用operator new 与 operator delete而不是malloc与free?
1.类安全
operator new 与 operator delete是针对特定的类进行内存分配与释放的,所以会考虑到类的大小以及构造与析构函数的调用
malloc与free不关心分配内存的类型也不会调用如何构造与析构函数,可能会在处理类对象的时候发生异常。
2.是否可重载
operator new 与 operator delete可重载
malloc与free不可重载
3.异常处理
operator new分配内存失败后会抛异常
malloc分配内存失败后会返回NULL
虽然operator new 与 operator delete和malloc与free都用于内存的分配与释放,但是operator new 与 operator delete更加适合在c++中使用,因为对比malloc与free具有更好的类安全性与灵活性。
区别对比
c++使用new与delete优点
1.简化用法
2.解决动态申请内存自定义对象初始化问题
内存泄漏
什么是内存泄漏:
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
内存泄漏的危害:
长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。
如果你使用某个app让你的设备越来越卡,最后只能重启设备来恢复,那八成就是内存泄漏了,可能还会吐槽一下:哪个****程序员写的****代码