目录
1. C/C++内存分布
2. C语言中动态内存管理方式
3. C++内存管理方式
3.1 new/delete操作内置类型
3.2 new/delete操作自定义类型
4. operator new与operator delete函数
4.1 operator new与operator delete函数(重点)
4.2 重载operator new和operator delete(了解)
5. new和delete的实现原理
5.1 内置类型
5.2 自定义类型
6. 定位new表达式(placement-new)(了解)
7. 常见面试题
7.1 malloc/free和new/delete的区别
7.2 内存泄漏
7.2.1 什么是内存泄漏,内存泄漏的危害
7.2.2 内存泄漏分类(了解)
7.2.3 如何检测内存泄漏(了解)
7.2.4 如何避免内存泄漏
1. C/C++内存分布
下面先看一段代码,通过这段代码简单分析C/C+的内存分布。
int globalVar = 3;
static int staticGlobalVar = 3;
void Test()
{
static int staticVar = 7;
int localVar = 7;
int num1[10] = { 1, 2, 3, 4, 5 };
const char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);
}
说明:
-
栈又叫做堆栈 -- 存储非静态局部变量/函数参数/返回值等,栈是向下增长的
-
内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库,用户可使用系统接口创建共享内存,叫做进程间通信(这部分在Linux中会讲的比较详细,现在了解一下即可)
-
堆用于程序运行时动态内存分配,堆是可以向上增长的
-
数据段 -- 存储全局数据和静态数据
-
代码段 -- 存储可执行的代码/只读常量
2. C语言中动态内存管理方式
这里稍微复习一下C语言中的动态内存管理方式,主要是通过malloc/calloc/realloc/free这几个函数去实现,他们的具体用法如下:
-
malloc
void* malloc(size_t _Size)
形参_Size为要申请空间的大小(字节数),若函数执行成功,则返回获得的内存空间的首地址,若函数执行失败,返回NULL。需注意malloc函数分配得到的空间是未初始化的,所以在malloc得到堆内存后一般可配合memset函数来初始化
-
calloc
void* calloc(size_t _Count, size_t _Size);
形参_Count为申请类型的个数,_Size为单个类型的大小,返回值和malloc一样。与malloc的一个显著区别的calloc函数获得的空间是经过初始化的,且初始化为0
-
realloc
void* realloc(void* _Block, size_t _Size);
形参_Block为堆上已经存在的空间的首地址,_Size为新空间的大小(字节数)。realloc函数的功能比malloc函数和calloc函数更为丰富,可以实现新内存分配和旧内存释放的功能。其功能为将_Block指向的堆内存块的大小改变为_Size字节,若_Size小于_Block之前指向的空间大小,则原地缩容;若_Size大于_Block之前指向的空间大小,且后面的空间足够时,原地扩容,反之,若后面的空间不够,则异地扩容,重新找一块大小为_Size的空间,将原来的数据拷贝到新空间后,_Block指向该新空间,并释放旧空间。另外,realloc函数分配的空间也是未初始化的
-
free
void free(void* _Block);
形参_Block是通过上面三个函数获得的堆空间地址,free函数常和上面三个函数配合使用,主要功能就是将_Block指向的堆空间释放
面试题:malloc/calloc/realloc的区别是?
-
相同点:
- 都是从堆上申请空间
- 都需要对返回值判空(NULL)
- 都需要用户自己调用free释放
- 返回类型相同(void*)
- 都需要类型转换(对返回值强制转换)
- 底层实现上是一样的,除了要申请的空间外,都需要开辟多余的空间,用来维护申请的空间(以防越界)
-
不同点:
- 函数名/参数列表不同
- calloc会对申请的空间初始化为0,另外两个不会
- malloc申请的空间常常使用memset初始化
- realloc是对已存在的空间进行调整,当第一个参数传入NULL时,函数功能和malloc一样
3. C++内存管理方式
因为C++兼容C,所以C语言内存管理方式在C++仍可以继续使用,但有些地方却也是无能为力,而且比较麻烦
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)