1、了解内存
2.C语言动态内存管理
C语言使用malloc/calloc/realloc在堆上进行空间开辟,使用free进行空间释放; malloc和free都声明在头文件 stdlib.h 中
2.1malloc
(1)函数原型:void* malloc(size_t size)
(2)参数:内存空间的长度
(3)返回值:返回值是一个指向开辟空间的起始地址的一个指针
- 如果开辟成功,则但会一个指向开辟好空间的指针
- 如果开辟失败,则返回一个空指针
- 返回值void*,所以malloc函数并不知道开辟空间的类型,要等到具体使用时才知道
- malloc只开空间并不对数据进行初始化,调用函数memset来初始化
2.2calloc
(1)函数原型:void* calloc(size_t num,size_t size)
(2)参数:元素个数为num,每个元素的大小为size
(3)函数功能:为num 个大小为size的元素开辟一块空间,并把空间的每个字节初始化(字符类或整形初始化为0;指针类型初始化为空指针)
与malloc的区别:
- calloc不仅会开辟空间,而且还会把数据初始化为0
- 根据实际情况,malloc比calloc快
2.3realloc
(1)函数原型:void *realloc(void *ptr,size_t size);
(2)参数:ptr为原有空间地址,size是重新申请的地址空间
(3)函数功能:对原有指针所指向的空间进行扩大或缩小,原有地址空间的内容保持不变。
(4)realloc在调整内存空间的时候存在两种情况:
- 原有空间之后有足够大的空间 :扩展内存就直接在原有内存之后直接追加空间,原来空间的数据不发生变化,并且返回的地址就是原来的地址
- 原有空间之后没有足够大的空间 :在堆空间上另找一个合适大小的连续空间来使用,这样函数返回的地址是一个新的地址。
2.4 free
堆上的内存要用户自己管理,开辟空间后一定要用free释放空间,否则会发生内存泄漏。
3.C++动态内存开辟
C++可以适应C语言的malloc/free/calloc/realloc来开辟空间,也可以使用new/delete,new[]/delete[]来动态管理内存。
C++兼容C语言,所以对malloc等的使用与C语言一致,此处不细说。
3.1 new/delete:动态管理对象
(1)用法:
int* p1=new int;//动态开辟4字节空间
delete p1;
int *p2=new int(4);//动态开辟4字节空间并初始化
delete p2;
(2)调用原理:
在函数体内 使用new运算符时,会跳转到operator new函数->利用malloc申请空间->调用构造函数->返回开辟空间首地址
在函数体内 使用delete运算符时,会跳转到operator delete函数->再调用析构函数->在函数体内再利用free释放空间。
(3)代码实现
class A
{
public:
A()
{
_a = 0;
cout << "构造AA()" << endl;
}
~A()
{
cout << "析构~AA()" << endl;
}
private:
int _a;
};
int main()
{
A* p1 = new A;
delete p1;
return 0;
}
结果:
3.2 new[]/delete[]:动态管理对象数组
(1)用法
int *p4=new int[3];//开辟3个大小的整形空间
delete[] p4;
(2)调用原理
在函数体内使用new[]运算符时,会跳转到operator new[]函数->利用malloc开空间->调用构造函数初始化->返回开辟首地址
在函数体内使用delete[]运算符时,会跳转到operator delete[]函数->调用析构函数->调用free释放空间
4.C++兼容C语言,已经有了malloc/free进行动态内存管理,为什么还要有new/delete?
C++是面向对象语言,在C++申请对象时,要调用构造函数和析构函数,这是编译器自动调用的。但是malloc/free是C语言的库函数,不在编译的控制权限,所以不能强行调用构造函数与析构函数。为了更好地使C++进行都太内存分配,才需要new/delete运算符。
5.malloc/free与new/delete的区别
(1)malloc/free是C库函数,而new/delete是运算符;都可以申请动态内存与释放内存
(2)malloc/free只是分配/释放空间,而new/delete不仅分配/释放空间,而且在分配时调用构造函数、在释放时调用析构函数
(3)malloc/free必须给定类型大小,返回void*;而new/delete自动计算类型大小,返回对应类型的指针
(4)malloc/free失败则返回0;new/delete失败则抛异常
参考:(https://blog.csdn.net/qq_39295755/article/details/78446665)