目录
1.回顾C语言内存管理
malloc:
//void* malloc(size_t n)
int* a=(int*)malloc(10*sizeof(int));
calloc:
//void* calloc(size_t _NumofElement,size_t _SizeofElemnt)
int* a=(int*)calloc(10,10*sizeof(int));
realloc:
//void* realloc(void* ptr,size_t n) 重新给ptr开辟空间
char* p1=(char*)malloc(10*sizeof(char));
char* p2=(char*)realloc(p1,25);
free(p2);
这里注意不要重复释放内存就行了,释放一个就行了
2.C++内存管理
用new,delete开辟内存(内置类型)
注意匹配
int* a1=new int;
delete a1;
//申请一个初始化为5的int
int* a2=new int(5);
delete a2;
//申请一个数组
int* b1=new int[5];
delete[] b1;
//C++11支持new[]用{}初始化,C++98不支持
int* b2=new int[5]{1,2,3};
delete[] b2;
对于内置类型:C++只不过是简化了用法,与C并无本质区别
而对于自定义类型:C语言只负责开辟空间,而C++new还调用了A的默认构造函数初始化空间,delete还调用了A的析构函数,释放空间
A* a=new A;
delete a;
A* a1=new A[10]{1,2,3,4};//隐式类型转换
A* a2=new A[10]{A(1),A(2)};//调用拷贝构造函数
delete[] a1;
delete[] a2;
(注意类要提供默认构造函数)
C语言还需要用过返回值来判断内存是否开辟成功,而new失败是抛出异常
结论:new/delete其实是为了自定义类型准备的。编译器为我们做了更多的事情,在某些场景使用C会变得麻烦
3.剖析底层原理
new/delete其实是关键字
我们观察反汇编:
观察反汇编实际上new是调用了operator new 函数和 A的默认构造
而operator new实际上还是调用了malloc函数。包括operator new[]也调用了malloc
delete其实也如此
4.扩展应用
在类中定义一个operator new函数,new对象的时候会优先调用这个类中的函数,这也算是C++的一个特性,在一些需要频繁开辟内存的场景下,采用池化技术就是如此。
5.new的补充用法
定位new:只开辟了空间却没有初始化的自定义对象
自定义类型调用默认构造函数的时机只有在定义和new的时候会调用
A* a=(A*)malloc(sizeof(A));
new(a)A;//默认构造
//也可以调用带参构造
最后,贴一张八股
1.语法使用的区别
2.本质功能的区别