【C++】:内存管理:C++内存分布 || C++中动态内存管理(new || delete)

在这里插入图片描述

📭1. C/C++内存分布

在这里插入图片描述
【说明】
🃏1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的
🃏2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
🃏3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
🃏4. 数据段–存储全局数据和静态数据。
🃏5. 代码段–可执行的代码/只读常量
我们先来看下面的一段代码和相关问题

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在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____
char2在哪里?____ *char2在哪里?___
pChar3在哪里?___ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____
🍡2. 填空题:
sizeof(num1) = ____
sizeof(char2) = ____ strlen(char2) = ____
sizeof(pChar3) = ____ strlen(pChar3) = ____
sizeof(ptr1) = ____
3. sizeof 和 strlen 区别?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

📮2.C语言中动态内存管理方式:malloc/calloc/realloc/free

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}

【面试题】
🚈 1. malloc/calloc/realloc的区别?
🚈 2. malloc的实现原理?
glibc中malloc实现原理
glibc中malloc实现原理

🎢3. C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理
new/delete操作内置类型

void Test()
{
// 动态申请一个int类型的空间
int* ptr4 = new int;
// 动态申请一个int类型的空间并初始化为10
int* ptr5 = new int(10);
// 动态申请10个int类型的空间
int* ptr6 = new int[3];
delete ptr4;
delete ptr5;
delete[] ptr6;
}

在这里插入图片描述
注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[ ]和delete[ ] 注意:匹配起来使用

int main()
{
	int* p2 = (int*)malloc(sizeof(int));
	// 自动计算大小,不需要强转 
	int* p3 = new int;

	int* p4 = (int*)malloc(sizeof(int)*10);
	int* p5 = new int[10];

	free(p2);
	free(p4);

	delete p3;
	delete[] p5;

	// 额外支持开空间+初始化
	int* p6 = new int(10);
	int* p7 = new int[10]{1,2,3};
	int* p8 = new int[10]{};

	return 0;
}int main()
{
	int* p2 = (int*)malloc(sizeof(int));
	// 自动计算大小,不需要强转 
	int* p3 = new int;

	int* p4 = (int*)malloc(sizeof(int)*10);
	int* p5 = new int[10];

	free(p2);
	free(p4);

	delete p3;
	delete[] p5;

	// 额外支持开空间+初始化
	int* p6 = new int(10);
	int* p7 = new int[10]{1,2,3};
	int* p8 = new int[10]{};

	return 0;
}int main()
{
	int* p2 = (int*)malloc(sizeof(int));
	// 自动计算大小,不需要强转 
	int* p3 = new int;

	int* p4 = (int*)malloc(sizeof(int)*10);
	int* p5 = new int[10];

	free(p2);
	free(p4);

	delete p3;
	delete[] p5;

	// 额外支持开空间+初始化
	int* p6 = new int(10);
	int* p7 = new int[10]{1,2,3};
	int* p8 = new int[10]{};

	return 0;
}

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

	~A()
	{
		cout << "~A():" << this << endl;
	}

private:
	int _a;
};

struct ListNode
{
	ListNode* _next;
	int _val;

	ListNode(int val = 0)
		:_val(0)
		, _next(nullptr)
	{}
};

int main()
{
	 malloc没有办法很好支持动态申请的自定义对象初始化
	A* p1 = (A*)malloc(sizeof(A));
	p1->_a = 0;
	p1->A(1);

	 自定义类型,开空间+调用构造函数初始化
	A* p2 = new A;
	A* p3 = new A(3);

	 自定义类型,调用析构函数+释放空间
	delete p2;
	delete p3;

	A* p4 = new A[10];
	delete[] p4;

	A aa1(1);
	A aa2(2);
	A* p5 = new A[10]{ aa1, aa2 };
	delete[] p5;


	A* p6 = new A[10]{ A(1), A(2) };
	delete[] p6;

	A* p7 = new A[10]{ 1, 2 };
	delete[] p7;

	ListNode* n1 = new ListNode(1);
	ListNode* n2 = new ListNode(2);
	ListNode* n3 = new ListNode(3);
	ListNode* n4 = new ListNode(4);
	ListNode* n5 = new ListNode(5);

	n1->_next = n2;
	n2->_next = n3;
	n3->_next = n4;
	n4->_next = n5;
	return 0;
}

new和delete操作自定义类型

class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
还会调用构造函数和析构函数
A* p1 = (A*)malloc(sizeof(A));
A* p2 = new A(1);
free(p1);
delete p2;
// 内置类型是几乎是一样的
int* p3 = (int*)malloc(sizeof(int)); // C
int* p4 = new int;
free(p3);
delete p4;
A* p5 = (A*)malloc(sizeof(A)*10);
A* p6 = new A[10];
free(p5);
delete[] p6;
return 0;

注意:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/134710.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

跨域:利用CORS实现跨域访问

跨域知识点&#xff1a;跨域知识点 iframe实现跨域的四种方式&#xff1a;iframe实现跨域 JSONP和WebSocket实现跨域&#xff1a;jsonp和websocket实现跨域 目录 cors介绍 简介 两种请求 简单请求 基本流程 withCredentials 属性 非简单请求 预检请求 预检请求的回应 …

利用OGG实现PostgreSQL实时同步

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

postman接口测试—Restful接口开发与测试

开发完接口&#xff0c;接下来我们需要对我们开发的接口进行测试。接口测试的方法比较多&#xff0c;使用接口工具或者Python来测试都可以&#xff0c;工具方面比如之前我们学习过的Postman或者Jmeter &#xff0c;Python脚本测试可以使用Requests unittest来测试。 测试思路…

GPT 写作与改编

GPT 写作与改编 文商科GPT 写作收益 改编技巧【改编一段话】【改编评价】【意识预设】落差&#xff0c;让顾客看到就感性和冲动害怕&#xff0c;让顾客看到就想买和拥有画面&#xff0c;切换空间&#xff0c;瞬间代入&#xff0c;勾人魂魄对比&#xff0c;设置参考物&#xff0…

RT-DETR推理详解及部署实现

目录 前言1. RT-DETR-官方2. RT-DETR-U版2.1 RT-DETR预测2.2 RT-DETR预处理2.3 RT-DETR后处理2.4 RT-DETR推理 3. RT-DETR-C3.1 ONNX导出3.2 RT-DETR预处理3.3 RT-DETR后处理3.4 RT-DETR推理 4. RT-DETR部署4.1 源码下载4.2 环境配置4.2.1 配置CMakeLists.txt4.2.2 配置Makefil…

有奖 | Python 开发者 2023 年度调查

你好&#xff0c;我是 EarlGrey&#xff0c;一名双语学习者&#xff0c;会一点编程&#xff0c;目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。 点击上方蓝字关注我&#xff0c;持续接收优质好书、高效工具和赚钱机会&#xff0c;一起提升认知和思维。 1…

免费分享一套基于Springboot+Vue的在线考试系统,挺漂亮的

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringbootVue的在线考试系统&#xff0c;分享下哈。 项目视频演示 【免费】springbootvue在线考试系统 Java毕业设计_哔哩哔哩_bilibili【免费】springbootvue在线考试系统 Java毕业设计项目来自互联网&a…

notes_质谱蛋白组学数据分析基础知识

目录 1. 蛋白组学方法学1.1 液相-质谱法1) 基本原理2) bottom-up策略的基本流程 1.2 PEA/Olink 2. 质谱数据分析2.1 原始数据格式2.2 分析过程1&#xff09;鉴定2&#xff09;定量3&#xff09;预处理 2.3 下游分析 参考附录 1. 蛋白组学方法学 目前常见的蛋白组学方法学如下图…

Pinme POS无代码开发集成营销系统,实现广告推广自动化

无代码开发平台的优势 无代码开发平台如集简云是一款超级软件连接器&#xff0c;无需开发&#xff0c;无需代码知识就可以轻松打通千款软件之间的数据连接&#xff0c;构建自动化与智能化的业务流程。这种方式无需花费数周甚至数个月的时间做软件集成开发&#xff0c;最快20分…

【中国知名企业高管团队】系列65:方太FOTILE

今天华研荟为您介绍另一个行业的知名企业和高管团队信息——厨房电器这个细分领域&#xff0c;也产生了许多大的公司&#xff0c;而且这些头部公司都集中在一起&#xff0c;是当地重要的一个产业集群。 首先介绍细分领域的、号称做高端的方太厨电FOTILE。 一、关于方太集团FO…

JavaWeb Day08 Mybatis-入门

目录 ​编辑​编辑​编辑 一、快速入门程序 ①准备工作 ②引入Mybatis相关依赖&#xff0c;配置Mybatis ③编写SQL&#xff08;注解/XML&#xff09; ④单元测试 ⑤相关代码 1.pom.xml 2. application.properties 3.User.java 4. UserMapper.java 5.Test.java ⑥配置…

网络运维Day10

文章目录 SHELL基础查看有哪些解释器使用usermod修改用户解释器BASH基本特性 shell脚本的设计与运行编写问世脚本脚本格式规范执行shell脚本方法一方法二实验 变量自定义变量环境变量位置变量案例 预定义变量 变量的扩展运用多种引号的区别双引号的应用单引号的应用反撇号或$()…

【星海随笔】SDN neutron (三) Service-plugin

Neutron L3 L3的实现只负责路由的功能&#xff0c;传统路由器中的其他功能&#xff08;如Firewalls、LB、VPN&#xff09;都被独立出来实现了&#xff0c;因此ML3的实际需求比较少。 neutron-server 接到请求 –> 将请求发送到MQ –> neotron-plugins 得到请求 –> 发…

编程艺术之源:深入了解设计模式和设计原则

深入了解设计模式和设计原则 一、认识设计模式1.1、设计模式是什么&#xff1f;1.2、设计模式是怎么来的&#xff1f;1.3、设计模式解决了什么问题&#xff1f; 二、设计模式的基础2.1、面向对象思想2.2、设计原则 三、如何学习设计模式3.1、明确目的3.2、学习步骤 总结 一、认…

HTML跳转锚点

跳转锚点适用于本页面和其他页面的任意标签的跳转以及JavaScript的运行 使用方法即给标签加上独一无二的id属性&#xff0c;再使用a标签跳转 如果是其他页面的标签只需加上其他页面的路径&#xff0c;eg.href"其他页面的路径#zp1" id属性的最好不要使用数字开头 <…

Vert.x学习笔记-什么是Verticle

什么是Verticle Verticle是Vert.x应用中的基本编程单元&#xff0c;类似于Java中的Servlet、Pojo Bean或Akka中的Actor。它可以使用不同的编程语言实现&#xff0c;并且这些由不同编程语言实现的Verticle可以封装到一个模块中&#xff0c;进而部署到一个Vert.x应用中。Verticl…

关系型数据库Redis安装与写入数据

文章目录 安装和初步选择数据库创建键值对数据类型 安装和初步 安装 Redis是开源的跨平台非关系型数据库&#xff0c;特点是占用资源低、查询速度快。 首先&#xff0c;在Github上下载最新发布的Redis-xxxx.zip压缩文件&#xff0c;下载之后解压&#xff0c;并将解压后的路径…

要找事做,我真怕被闲死

要找事做&#xff0c;我真怕被闲死 | 昨晚睡足了5个多小时&#xff0c;元气开始恢复&#xff0c;今晨6点钟醒来&#xff0c;如厕后无睡意&#xff0c;便窝在被子里闭目养神&#xff0c;同时想心事。 7点钟翻身起床穿衣洗刷后&#xff0c;烧瓶开水泡杯浓茶&#xff0c;打开电脑…

如何关闭Windows Defender(亲测可行!!非常简单)

一、背景 Windows Defender&#xff08;简称WD&#xff09;真的太讨厌了&#xff0c;经常给你报你下载的文件是病毒&#xff0c;且不说真的是不是病毒&#xff0c;它都不询问直接删。 另外聚资料显示WD还会不合时宜地执行扫描导致系统变慢&#xff08;不会在合适的、空闲的时…

Linux shell编程学习笔记24:函数定义和使用

为了实现模块化设计和代码重用&#xff0c;很多编程语言支持函数或过程&#xff0c;Linux shell也支持函数定义和调用。 Linux shell中的函数与其它编程语言很多有相似之处&#xff0c;也有自己独特之处。 1 函数的定义 1.1 标准格式 function 函数名(){语句或命令1……语句…