C++内存管理

目录

    • 一.内存分布
    • 二.动态内存管理方式
      • 1. c语言内存管理
      • 2. C++内存管理
        • a. 内置类型
        • b. 自定义类型
    • 三.new 和 delete的实现原理
      • 1. operator new函数
      • 2. operator delete函数
      • 3. new []与delete[]
    • 四.定位new 表达式

一.内存分布

C++内存管理_第1张图片

  1. :又叫堆栈,存储非静态局部变量、函数参数、返回值等等,栈是向下增长的。
  2. :用于程序运行时动态内存分配,堆是可以上增长的。
  3. 数据段:存储全局数据和静态数据。
  4. 代码段:存储可执行的代码/只读常量

二.动态内存管理方式

1. c语言内存管理

使用malloccallocreallocfree

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:释放动态开辟的空间

2. C++内存管理

a. 内置类型

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[]。需要匹配使用。

b. 自定义类型

C++内存管理_第2张图片

对于自定义类型,new会调用构造函数,delete会调用析构函数,而malloc与free不会 ,但都会在堆上开辟空间。

new开辟空间,申请失败会抛异常。malloc申请空间,需要检测返回值,失败返回空指针。

三.new 和 delete的实现原理

1. operator new函数

new是用户进行动态内存申请的操作符,new在底层调用operator new()全局函数来申请空间,在operator new函数体中,是使用malloc() 来申请空间。

用operator new来封装malloc的做法,主要是为了实现申请失败会抛出异常(bad_alloc)。

new 底层先调用operator new(),然后再调用自定义类型的构造函数()

2. operator delete函数

delete是用户进行动态内存释放的操作符,delete在底层调用operator delete()全局函数来释放空间,operator delete 最终也是通过free来释放空间

delete先调用自定义类型的析构函数(),再调用operator delete()

3. new []与delete[]

new [],实际上是调用operator new[] ()函数,在operator new[] ()函数中n次调用operator new()函数来申请空间。然后对于自定义类型,会调用n次构造函数

delete[] , 对于自定义类型先调用n次析构函数,然后再调用operator delete[] ()函数,实际在operator delete[]中调用operator delete()来释放空间

四.定位new 表达式

  • 语法:new(address) type
  • 功能:在已经申请好的空间处,调用type类的构造函数,进行初始化。

例:

//malloc只进行空间的申请
A* a = (A*)malloc(sizeof(A));

//定位new:调用A类的构造函数,完成初始化
new(a) A(9);

    观看~~

你可能感兴趣的:(一块来学C++,c++)