C/C++内存管理相关知识点

2023-09-21 21:09:55

1.内存分布

C/C++将内存大体上分为四个区域:栈区、堆区、静态区(数据段)、常量区(代码段)。

栈区:用来存储函数调用时的临时信息的结构,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。

堆区:程序员自己使用malloc或new自己申请出来存的地方。(动态内存分配)

静态区: static修饰的数据,全局数据,存放的位置。

常量区:不会改变的常量,存在这里。


看下面一段代码,回答问题:

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);
}

看上面一段代码,请回答如下:

在这里插入图片描述
在这里插入图片描述

2. new/delete关键字

2.1 操作内置类型

int main()
{

	//动态申请一个int 类型的空间
	int* ptr1 = new int;
	delete ptr1;			//释放ptr1
	
	// 动态申请一个int 类型的空间,并初始化为 5
	int* ptr2 = new int(5);
	delete ptr2;		   //释放ptr2

	// 动态申请5个int 类型的空间
	int* ptr3 = new int[5];
	delete[] ptr3;         // 释放ptr3,注意怎么new的怎么delete

	 动态申请5个int 类型的空间,并初始化
	int* ptr4 = new int[5]{ 1,2,3 };
	delete[] ptr4;		   // 释放ptr4,注意怎么new的怎么delete

	return 0;
}

**注意:new 对应 delete,new [] 对应 delete [] 。**不可用错。

操作自定义类型

new 和 delete 除了申请和释放空间外,会自动调用构造函数和析构函数。

class A
{
public:
	A(int a = 0)
	{
		cout << "A()" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}

private:
	int _day;
	int _year;
	int _month;
};

int main()
{
	A* p1 = new A(1);  //一次构造
	delete p1;			//一次析构

	A* p2 = new A[5];  // 五次构造
	delete[] p2;       //五次析构

	

	return 0;
}

3. opeartor new 与 operator delete函数

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

其中:
operator new:该函数实际通过malloc来申请空间,申请成功直接返回;失败时,尝试执行空间不足应对策略,如果用户对该措施设置了,继续申请空间,否则抛异常。

operator delete:该函数最终是通过free()来释放空间的。


在这里插入图片描述
通过该定义也可以看出,free()其实也是一个重命名,真正的函数名是后面的。

4. new 和 delete 原理

4.1 内置类型

如果申请的是内置类型空间,new和malloc,delete和free基本类似,不同的地方是:new和delete申请和释放的是单个元素空间,new[]和delete[]申请和释放的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

4.2 自定义类型

  • new的原理
    1.调用operator new 申请空间
    2.在申请的空间上执行构造函数,完成对象的构造。

  • delete 原理
    1.在空间上执行析构函数,完成对象中资源的清理工作
    2.调用operator delete函数释放对象的空间

  • newT[N] 原理
    1.调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请。
    2.在申请的空间上执行N次构造函数

  • delete[] 原理
    1.在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。
    2.调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间

如下例子总结:
在这里插入图片描述

5.定位new表达式(placement-new)

定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。

使用语法:
new (place_address) type 或者new (place_address) type(initializer-list)
place_address必须是一个指针,initializer-list是类型的初始化列表。


new(p1)A;    //如果A的构造函数有参数,此处需要传参
nwe(p2)A(10);  // 初始化参数为10

6. malloc/free 和 new/delete的区别

共同点:
都是从堆上申请空间,并需要手动释放。

不同点:

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

7. 内存泄漏

相关知识后续会继续补充。。。

更多推荐

Python协程(asyncio)(一)协程开发

协程的概念协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源)。为啥说它是一个执行单元,因为它自带CPU上下文。这样只要在合适的时机,我们可以把一个协程切换到另一个协程。只要这个过程中保存或恢复CPU上下文那么程序还是可以运行的。通俗的理解:在一个线程中的某个函数,可以在

Redis实战(10)-一条命令在Redis是如何执行的?

RedisServer一旦和某客户端建立连接,就会在事件驱动框架中注册可读事件,对应客户端的命令请求。整个命令处理过程可分阶段:命令解析,processInputBufferAndReplicate命令执行,processCommand结果返回,addReply1命令读取:readQueryFromClient会从客户

JavaScript 设计模式中的 this、call 和 apply(设计模式与开发实践 P3)

文章目录2.1thisthis作为对象的方法this作为普通函数构造器调用call和apply2.2call和apply修正函数中的this模拟bind函数借用其他对象的方法2.1thisjavascript的this总是指向一个对象,且指向的对象基于函数的执行环境动态绑定,而不是函数声明时的环境this作为对象的方法

【校招VIP】前端JS语言之CSS基础属性

考点介绍CSS全称为CascadingStyleSheets,中文翻译为“层叠样式表”,简称CSS样式表,所以称之为层叠样式表(CascadingStylesheet)简称CSS。在网页制作时采用CSS技术,可以有效地对页面的布局、字体、颜色、背景和其它效果实现更加精确的控制。前端JS语言之CSS基础属性-相关题目及解

联合matlab和Arcgis进行netcdf格式的雪覆盖数据的重新投影栅格

图片摘要本专栏目的是将netcdf格式的雪覆盖数据进行重新投影,需要使用的工具包括matlab和Arcgis,下面进入正题。1.数据的下载与读取---matlab最近我需要读取北半球的冰雪覆盖数据,下载的是MODIS/TerraSnowCoverMonthlyL3Global0.05DegCMG,Version61,文

使用 Pandas 在 Python 中读写 JSON 文件

介绍Pandas是最常用的数据处理和可视化Python库之一。Pandas库提供了可用于高效读取、操作和可视化以各种文件格式存储的数据的类和功能。在本文中,我们将使用Python和Pandas读取和写入JSON文件。什么是JSON文件?JavaScript对象表示法(JSON)是一种以人类可读形式存储数据的数据格式。虽

Git:利用Git模拟企业级项目管理

文章目录基础知识Git分支设计规范master分支release分支develop分支feature分支hotfix分支模拟进行企业级项目管理本篇主要总结的是企业级开发模型以及利用Git模拟企业级别的项目管理方式基础知识前面已经进行了全部的关于Git的各项操作,那么Git是作用于企业项目管理的,因此了解企业是如何进行项

【离网逆变器】离网逆变器型号由一个高频DC-DC升压转换器与全桥PI控制电压源逆变器级联组成、逆变器使用带LC滤波器的SPWM调制(Simulink)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2运行结果🎉3参考文献🌈4Simulink实现💥1概述本文离网逆变器型号具备令人印象深刻的功能和性能。它

基于SSM的出租车管理系统的设计与实现

末尾获取源码开发语言:JavaJava开发工具:JDK1.8后端框架:SSM前端:采用JSP技术开发数据库:MySQL5.7和Navicat管理工具结合服务器:Tomcat8.5开发软件:IDEA/Eclipse是否Maven项目:是目录一、项目简介二、系统功能三、系统项目截图管理员功能实现员工功能实现​编辑驾驶员功能

如何摆脱产品同质化现象?请你做好反向行动

01:被违反的经济学原理经济学的基本原理之一是价格与需求之间存在反比关系。然而,大家见过两款功能几乎相同的垃圾袋却出现了价格与需求不成反比的情况。一款垃圾袋售价39元却能卖到20万的销量额而另一款垃圾袋售价几块却只有几千的销量你知道为什么吗?02:卖点过多会导致用户困惑有一句话说:“过犹不及”,这也适用于产品的卖点。如

基于矩阵分解算法的智能Steam游戏AI推荐系统——深度学习算法应用(含python、ipynb工程源码)+数据集(四)

目录前言总体设计系统整体结构图系统流程图运行环境模块实现1.数据预处理2.模型构建1)定义模型结构2)优化损失函数3.模型训练及保存1)模型训练2)模型保存4.模型应用1)制作页面2)模型导入及调用3)模型应用代码系统测试1.训练准确率2.测试效果3.模型应用1)程序使用说明2)测试结果相关其它博客工程源代码下载其它资

热文推荐