- 栈:又叫堆栈,存储非静态局部变量、函数参数、返回值等等,栈是向下增长的。
- 堆:用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段:存储全局数据和静态数据。
- 代码段:存储可执行的代码/只读常量
使用malloc
、calloc
、realloc
、free
void Test()
{
char* str1 = (char*)malloc(10);
char* str2 = (char)calloc(5, 1);
char* str3 = (char*)realloc(str2, 20);
free(str1);
free(str3);
}
malloc:向堆申请一块连续的大小为10 字节的空间
calloc:为5个大小为sizeof(char)的元素开辟空间,并把空间每个字节都初始化为0
realloc:为str2重新申请大小为sizeof(char)*20字节的空间,如果str2空间后有足够空间,则在原有空间后追加新增空间;如果没有足够可用空间,则在堆中其他地方开辟连续的空间,并将原空间的数据拷贝过来,然后释放原空间。
free:释放动态开辟的空间
c++兼容c语法,但为了使用更加方便,提出自己的内存管理方式:用new和delete操作符进行动态内存管理
void Test()
{
//申请1个int的空间
int* p1 = new int;
//申请1个int空间,初始化为10
int* p2 = new int(10);
//申请10个int空间
int* p3 = new int[10];
//C++11支持{}初始化,C++98不支持
int* p4 = new int[10]{2022,9,10};
delete p1,p2;
delete[] p3,p4;
}
单个元素的申请和释放,使用new和delete操作符。
连续空间的申请和释放,使用new[]和delete[]。需要匹配使用。
对于自定义类型,new会调用构造函数,delete会调用析构函数,而malloc与free不会 ,但都会在堆上开辟空间。
new开辟空间,申请失败会抛异常。malloc申请空间,需要检测返回值,失败返回空指针。
new是用户进行动态内存申请的操作符,new在底层调用operator new()全局函数来申请空间,在operator new函数体中,是使用malloc() 来申请空间。
用operator new来封装malloc的做法,主要是为了实现申请失败会抛出异常(bad_alloc)。
new 底层先调用operator new(),然后再调用自定义类型的构造函数()
delete是用户进行动态内存释放的操作符,delete在底层调用operator delete()全局函数来释放空间,operator delete 最终也是通过free来释放空间
delete先调用自定义类型的析构函数(),再调用operator delete()
new [],实际上是调用
operator new[] ()
函数,在operator new[] ()函数中n次调用operator new()
函数来申请空间。然后对于自定义类型,会调用n次构造函数
delete[] , 对于自定义类型先调用n次析构函数,然后再调用
operator delete[] ()
函数,实际在operator delete[]中调用operator delete()
来释放空间
例:
//malloc只进行空间的申请
A* a = (A*)malloc(sizeof(A));
//定位new:调用A类的构造函数,完成初始化
new(a) A(9);
观看~~