动态内存管理
<一>c语言中有关动态内存管理的操作
c语言是面向过程的程序设计语言,其过程主要以函数来实现。
c语言中,有关动态内存管理的函数主要有以下三种:
- void *malloc(size_t size)
- calloc
- realloc
<二> c++中有关动态内存管理的操作符及函数
- new / delete操作符
- new[ ] / delete [ ]
- operator new() / operator delete()
<三>new/malloc的底层实现
new操作符 —> operator new() + 构造函数 —> malloc() +构造函数
delete操作符 —> 析构函数 + operator delete() —> 析构函数 + free()
<四>new/delete和malloc/free的区别
主要有以下几个方面差异:
- 内容上的区别
- 本质上的区别
- 用法上的区别
<五>注意事项
使用时,切记:开辟和释放内存,一定要匹配使用。如:使用malloc开辟的空间,对应使用free释放;使用new开辟的空间,对应使用delete释放
class AA
{
AA()
{
cout<<"AA()"<<endl;
}
~AA()
{
cout<<"~AA()"<<endl;
}
};
int main()
{
//1.内置类型
int *p1=(int *)malloc(sizeof(int)*4);
free (p1); //正确用法
//delete p1; //不会崩溃,不会报错
int *p2=new int;
delete p2; //正确用法
delete []p2; //程序崩溃(越界访问)
free(p2); //不会崩溃,不会报错
//2.自定义类型
AA *p3=new AA;
delete p3; //正确用法
delete []p3; //程序崩溃。(若AA类型无显式定义的析构函数,即其析构函数为系统默认的,则delete []不会向前偏移4个字节,程序不会崩溃)
free(p3); //不会崩溃,但有可能会内存泄漏
AA *p4=new AA[4];
delete p4[]; //正确用法
delete p4; //程序崩溃,释放内存不正确(若AA类型无显式定义的析构函数,即其析构函数为系统默认的,则new []不会多开辟4个字节存对象个数,故,程序不会崩溃)
free(p4); //程序崩溃,且有可能出现内存泄漏(在于自定义类型中是否有指针类型的成员变量),(若AA类型无显式定义的析构函数,即其析构函数为系统默认的,则new []不会多开辟4个字节存对象个数,故,程序不会崩溃)
}
严格的说,new[ ]:一定会多开辟4个字节的空间来记录对象个数,用于确定最后清理对象需要调用多少次析构函数
但编译器往往会进行优化:
1.new [ ]一个内置类型,不会多开辟4个字节大小的空间
2.当编译器识别到了析构函数可调用可不调用时(即:无显式定义的析构函数,其析构函数为系统默认的),new [ ]不会多开辟4个字节大小的空间。