c语言中使用malloc(进行动态开辟空间)、calloc(动态开辟空间,函数在返回前把内存初始化为0)、realloc(用于增容,用于修改一个原先已经分配的内存块大小)、free进行动态内存管理
c++通过new 和 delete动态管理内存
new/delete动态管理对象
new[]/delete[]动态管理对象组
void Test()
{
int* p4=new int; //动态分配4个字节(1个int)的空间
int* p5=new int(3) //动态分配4个字节(1个int)的空间并初始化为3
int* p6=new int[3] //动态分配12个字节(3个int)的空间
delete p4;
delete p5;
delete[]p6;
}
new和delete:操作符 int:类型 (3):初始化为3 [3]:对象个数为3
1. 对于内置类型:new和malloc本还没有区别
2. 对于自定义类型:malloc动态开辟空间;new 动态开辟空间、调用构造函数(初始化)、调用析构函数(清理)
注意!malloc/free、new/delete、new[]/delete[],一定要匹配使用,否则可能出现内存泄漏的问题
- 栈又叫堆栈:非静态局部变量、函数参数、返回值等等,栈是向下增长的
- 内存映射区:高效的I/O映射方式,用来装在一个共享的动态内存库
- 堆:用于程序运行时动态内存分配,堆是可以向上生长的
- 数据段:存储全局数据和静态数据
- 代码段:可执行的代码/只读常量
虚拟地址的好处:
- 保护物理地址
- 扩大空间,物理地址不够用
- 方便实现了父子进程的通信
static int a=10;
int b=10;
void func()
{
static int c=10;
int d=10;
char* p1="hello";
charp2[]="hello";
int* p3=(int*)malloc(4);
}
NUL字节是字符串的终止符,但本身并不是字符串的一部分,字符串的长度不包括NUL
1. strlen(p1)=5
2. strlrn(p2)=5
3. sizeof(p1)=4或8 p1为指针,在32平台为4,64为平台为8
4. sizeof(p2)=6 数组的大小,包括/0
A:栈(非静态局部变量,函数参数,返回值) B:堆(动态内存分配) C:数据段(全局数据和静态数据) D:代码段(常量区)
a C 静态数据
b C 全局数据
c C 静态数据
d A 非静态局部变量
p1 A 局部指针变量
p2 A 局部数组
p3 A 局部指针变量
*p1 D
*p2 A
*p3 B 动态内存分配
malloc/free和new/delete的区别和联系?
- 都是动态管理内存的入口
- malloc/free是C/C++的标准库函数,new/delete是C++操作符
- malloc/free只是动态分配内存空间、释放空间(malloc只是开辟了与对象具有相同大小的内存块空间)。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(new调用构造函数来创建对象)
- malloc/free需要手动计算类型大小且返回值为void*,new/delete可以自己计算类型的大小,返回对应类型性的指针
- malloc失败,返回0;new失败,抛出异常
new做了两件事:
- 调用operator new 分配空间
- 调用构造函数初始化对象
delete也做了两件事:
- 调用析构函数清理对象
- 调用operator delete释放空间
new[N]
- 调用operator new 分配空间
- 调用N次构造函数分别初始化每个对象
delete[N]
1. 调用N次析构函数清理对象
2. 调用operator delete释放空间
什么是内存泄漏:在堆上申请的空间没有释放
如何避免:良好的编程习惯,使用系统自带的工具(vs下crtdbg),自己实现检测工具,第三方检测工具