文章目录
一. 普通全局/局部变量 和 静态全局/局部变量的区别
二. C/C++ 内存分布
不同变量存在于不同的空间布局中,这些空间主要分为:栈,堆,数据段,代码段
- 栈:又叫堆栈,非静态局部变量/函数参数/返回值等等,栈是向下增长的比较小,只有 3M 左右
- 堆:用于程序运行时动态内存的分配,堆是向上增长的,它的空间很大
- 数据段:存储全局变量和静态变量,分为已初始化数据段和为初始化数据段
- 代码段:程序的代码,只读常量
三. C/C++ 内存管理方式
1. C 内存管理方式
PS:malloc/calloc/realloc/free 都是 C 库函数
1.1 malloc/calloc/realloc/free 的使用方法
2.1 malloc/calloc/realloc 使用效果的区别
- malloc:只是单纯的开辟空间
- calloc:开辟空间后,把空间内容一个字节一个字节的初始化为 0
- realloc:如果后面空间足够,在原有的空间上进行扩容;后面空间不够的话拷贝原空间的数据到新扩容的另一块空间上,并自动释放原空间。
2. C++ 内存管理方式
PS:new/delete 是操作符
C 语言内存管理方式在 C++ 中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此 C++ 又提出了自己的内存管理方式:通过new 和 delete 操作符进行动态内存管理。
申请和释放单个对象的空间,使用new 和 delete操作符,申请和释放连续的空间,使用new[] 和 delete[]
四. operator new 与 operator delete 函数
PS:operator new 和 operator delete 是系统提供的全局函数。
1. operator new
1.1 概念
底层还是以依靠 malloc 函数实现开辟空间,只不过增加了开辟空间失败后的抛异常功能(malloc开辟空间失败后返回 0)。
1.2 operator new 和 malloc 的区别
使用方式一样,处理错误的方式不一样
2 operator delete
2.1 概念
底层是通过 free 来释放空间的,为了与 operator new 配套才出现的,与 free 没什么区别。
2.2 operator delete 与 free
使用方式一样,处理错误的方式也一样(释放空间失败直接终止进程)。
五. new 和 delete 实现原理
- new:operator new + 构造函数
- delete:析构函数 + operator delete
1. 内置类型
new 和 malloc,delete 和 free 基本类似,就是空间开辟失败时处理错误的方式不一样。
2. 自定义类型
- new:调用 operator new 函数申请空间 + 调用构造函数完成初始化
- delete:调用析构函数完成清理工作 + 调用 operator delete 函数释放空间。
六. malloc/free 和 new/delete 的区别
使用
- 开辟连续空间时要用 new[ ] ,而 malloc 对于一个对象的空间和连续的空间都一样方法
- malloc 开辟空间要传具体的字节数,而 new 传对象空间的类型和数量
- new 返回值类型为对象类型的指针,malloc 返回类型为 void*
- new 失败后抛异常,malloc 失败后返回空指针
本质
- malloc/free 是函数,new/delete 是操作符
- 底层实现
- new -> operator new -> malloc + 抛异常
- free -> operator free -> free
七. 定位 new
对于自定义类型,new 开辟的空间会自动调用构造函数完成初始化。那么 malloc 开辟的自定义类型对象的空间怎么初始化呢?
1. 概念
在已分配的原始内存空间中显示调用构造函数初始化一个对象,它是一个操作符。
2. 用法
new (place_address) type 或者 new (place_address) type(initializer-list)
- place_address 必须是一个指针
- initializer-list 是类型的初始化列表
七. 内存泄漏
1. 概念
动态开辟出来的空间不要了,因为忘记或者其他原因没有释放这块空间,就造成内存泄漏
- 内存泄漏不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
- 区别野指针:野指针是一个指针变量指向了一块未知的地址
2. 危害
对长期运行的程序(如游戏后台服务)或者设备内存本身就很小的情况内存泄漏出现内存泄漏会导致响应越来越慢,最终卡死。
3. 如何避免内存泄漏
- 事前预防型:如智能指针等
- 事后查错型:如泄漏检测工具