首页 > 系统相关 >C++内存管理

C++内存管理

时间:2024-04-03 11:01:10浏览次数:27  
标签:malloc 管理 int C++ 空间 内存 operator new delete

内存管理

1、C/C++内存分布

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
 static int staticVar = 1;
 int localVar = 1;
 int num1[10] = { 1, 2, 3, 4 };
 char char2[] = "abcd";
 const char* pChar3 = "abcd";
 int* ptr1 = (int*)malloc(sizeof(int) * 4);
 int* ptr2 = (int*)calloc(4, sizeof(int));
 int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
 free(ptr1);
 free(ptr3);
}
  1. 选择题:
    选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
    globalVar在哪里?C__ static GlobalVar在哪里?C
    static Var在哪里?C localVar在哪里?A
    num1 在哪里?A

    char2在哪里?A *char2在哪里?A
    pChar3_A
    __ *pChar3在哪里?D
    ptr1在哪里?A__ *ptr1在哪里?B__

  2. 填空题:
    sizeof(num1) = 40;
    sizeof(char2) = 5; strlen(char2) = 4;
    sizeof(pChar3) = 4/8; strlen(pChar3) = 4;
    sizeof(ptr1) = 4/8;
    在这里插入图片描述

2、C++动态内存管理方式

2.1 new和delete

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。
可以说new和delete就是为了自定义对象出现。

  1. new的原理
    1. 调用operator new函数申请空间
    2. 在申请的空间上执行构造函数,完成对象的构造
  2. delete的原理
    1. 在空间上执行析构函数,完成对象中资源的清理工作
    2. 调用operator delete函数释放对象的空间
  3. new T[N]的原理
    1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
    2. 在申请的空间上执行N次构造函数
  4. delete[]的原理
    1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
    2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

在这里插入图片描述
malloc 和 free 、new 和 delete 要匹配使用!!!!
new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数.
如果我们进行资源分配后,没有调用析构函数,释放空间(堆上自己开辟的空间),就会造成资源泄露。
在这里插入图片描述
结论:malloc和new 有底层实现机制的关联交叉,不匹配使用,可能有问题,可能没问题,建议一定匹配使用

C语言和C++内存管理是一致的,但是动态内存管理(堆上面的)只能满足C语言,满足不了C++,所以C++搞了自己的一套,即 new 和 delete。

int main()
{
	//int* p = new int;//不会初始化
	int* p1 = new int(10);//会初始化
	int* p2 = new int[10];//申请10个int的 数组
	int* p3 = new int[10]{ 1,2,3,4 };//申请10个int的数组,并初始化为1,2,3,4

	delete p1;
	delete[] p2;
	delete[] p3;
	return 0;
}

2.2 operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

他们俩是系统提供的全局函数,不是函数重载。
其实底层也是用malloc和free来实现的,但是出错机制不同,malloc失败是返回nullptr,而new失败是抛异常。

operator new 底层是对 malloc失败进行封装,让他申请空间失败后抛异常

	//申请空间  operator new->封装malloc,失败抛异常
	//调用构造函数
	A* p2 = new A(1);
	//先调用析构函数
	//再释放p2指向的空间
	delete p2;

在这里插入图片描述
operator new[ ] 其实就是多了一层路径,operator new [ ] 再去调用operator new。只是为了与operator new 配对

	//申请空间 operator new[] -> operator new -> 封装malloc
	//申请10次构造函数
	A* p6 = new A[10];
	//先调 10次析构函数
	//在operator delete[] p6指向的空间。全部释放
	delete[] p6;

2.3 定位new

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new (place_address) type或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表

int main()
{
	A aa;
	A* p1 = (A*)malloc(sizeof(A));
	if (p1 == nullptr)
	{
		perror("malloc fail");
	}
	// 对一块已有的空间初始化 -- 定义new
	//new(p1)A;
	new(p1)A(1);//初始化为1

	p1->~A();
	free(p1);
	
	return 0;
}

在这里插入图片描述

3、附录

3.1 malloc/free和new/delete的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地 方是:

  1. malloc和free是函数,new和delete是操作符
  2. malloc申请的空间不会初始化,new可以初始化
  3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可
  4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常
  6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理

标签:malloc,管理,int,C++,空间,内存,operator,new,delete
From: https://blog.csdn.net/weixin_67466860/article/details/137255087

相关文章

  • Linux C++ 016-友元
    LinuxC++016-友元本节关键字:Linux、C++、友元及三种实现方式相关库函数:友元的概念及关键字friend在程序里,有些私有属性也可以让类外特殊的函数或者类进行访问,这就需要用到友元技术。友元的目的就是让一个函数或者类访问另一个类中私有成员。友元的三中实现方式(1......
  • Linux C++ 015-对象模型和this指针
    LinuxC++015-对象模型和this指针本节关键字:Linux、C++、对象模型、this指针相关库函数:成员变量和成员函数分开存储1、在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类的对象上;2、C++编译器会给每个空对象也分配一个字节的空间,是为了区分空对象占......
  • 解析基础设施即代码:重新定义云管理
    由于现代架构、应用程序接口和相互关联的服务之间的互联性越来越强,云基础设施的复杂性也与日俱增。随着需要管理的云资源数量不断增加,企业开始采用基础设施即代码(IaC)来解决云应用的复杂性和相互依赖性问题。 IaC提供各种工具、流程和方法,以简化基础设施管理、降低风险并采用新......
  • AWS通过交换机连接管理节点检查AWS云状态
    1、ceph集群检查要查看Ceph集群的状态,可以使用Ceph的命令行工具ceph。以下是一个基本的命令,它将提供Ceph集群的概览状态,包括集群的健康状况、OSD数量、PG状态等:ceph-s#这个命令会输出一个详细的状态报告,其中包括了集群的各种资源和服务的状态。cephosdtree|grep-E'host|......
  • 远程管理
    1、打开远程控制软件teamviewer手机版,选择右上角“齿轮”图标,2、进入到设置界面,选择“登录或注册”选项,3、往下滑动,选择下方“注册”选项,4、填写“电子邮箱”、“姓名”、“密码”和“确认密码”后,选择下方“注册”即可。teamviewer手机版如何控制电脑?1、打开电脑端Team......
  • debian10安装qt5库,解决安装ibudev-dev会卸载桌面和网络管理问题。以及libc6-dbg安装同
    直接使用sudoaptinstalllibudev-dev 命令安装会有问题。问题现象和根因:安装libudev-dev会卸载gdm3,network-manager等。继续执行它会卸载网络服务,桌面环境等,重启后黑屏。解决:使用aptitude安装。sudoaptinstallaptitudesudoaptitudeinstalllibudev1=241-7~deb10u10......
  • 在Linux中,有哪些系统管理和配置工具?
    在Linux系统中,有众多的系统管理和配置工具,这些工具涵盖了从基本的系统配置、网络管理、用户和权限管理、服务管理、系统监控、备份与恢复等诸多方面。以下列举了一些关键类别及其代表性工具:1.系统配置与初始化工具sysctl:用于动态调整内核参数的工具。/etc/sysctl.conf:配置内......
  • MongoDB用户权限管理,设置密码并连接
    MongoDB用户权限管理,设置密码并连接如何设置密码在服务启动状态下,在命令行中输入mongo;首先设置admin表的用户(必须,否则单独设置表用户无用),先执行useadmin,再执行db.createUser({user:'root',pwd:'123456',roles:['root']}),此时会创建一个名为root,密码为123456,角色为root的用......
  • Day 06 Linux的进程管理
    相关定义程序二进制文件,静态/usr/sbin/httpd,/usr/sbin/sshd,程序占用磁盘空间程序的两种状态:running和dead进程是程序运行的过程,动态,有生命周期的,可以产生和消亡的(进程是已启动的可执行程序的运行实例,实例即运行可执行程序),进程占用CPU和内存mem。父进程程序运行时产......
  • C++提高学习笔记
    C++提高学习笔记面向对象设计的基本概念面向对象的分析(OOA):解析出需求,需要做什么面向对象的设计(OOD):需要设计哪些类,类中有哪些数据成员,哪些成员函数,类与类之间的关系面向对象的变成(OOP):将需求与设计转换为代码UML语言:同一建模语言类与类之间的关系......