【C++】第五节:内存管理

news2024/10/12 12:29:17

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,全局变量和静态变量在静态区
staticGlobalVar 在 C
staticVar 在 C 
localVar 在 A
num1 在 A
char2 在 A,char2 也是一个变量
*char2 在 A,数组名是首元素的地址,解引用就是a,在栈上
字符串常量 "abcd" 存储在代码段的常量区,而指针变量 pChar3 存储在栈上
const char* pChar3 = "abcd";表示 pChar3 是一个指向 const char 的指针,指针 pChar3 指向的位置可以被更改,但是不能通过 pChar3 来修改它所指向的字符数据
pChar3 在 A
*pChar3 在 D
ptr1 在 A,ptr1是一个指针(局部变量),指向的空间在堆上
*ptr1 在 B

2. 填空题:
sizeof(num1) = 40;
sizeof(char2) = 5; 注意 sizeof 计算时包括最后的'\0'
strlen(char2) = 4;//遇到'\0'终止
sizeof(pChar3) = 4/8; 
strlen(pChar3) = 4;
sizeof(ptr1) = 4/8;

【说明】

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

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

void Test()
{
	int* p1 = (int*)malloc(sizeof(int));
	free(p1);

	int* p2 = (int*)calloc(4, sizeof(int));
	int* p3 = (int*)realloc(p2, sizeof(int) * 10);
	free(p3);
}

为什么不需要 free(p2) 呢?

因为如果 realloc 原地扩容,p2 和 p3 是一样的;如果是异地扩容,p2 在 realloc 成功后已经指向新的内存块,旧的内存块会自动释放。

malloc/calloc/realloc的区别?

// 分配指定字节数的未初始化内存
void* malloc (size_t size);

// 分配指定数量的元素并初始化为零
void* calloc (size_t num, size_t size);

// 调整以前分配的内存块的大小,可以扩大或缩小内存块
void* realloc (void* ptr, size_t size);

3、C++内存管理方式

3.1 new/delete操作内置类型

void Test()
{
	// 动态申请一个int类型的空间
	int* ptr1 = new int;

	// 动态申请一个int类型的空间并初始化为10
	int* ptr2 = new int(10);

	// 动态申请10个jin类型的空间
	int* ptr3 = new int[10];

	// 释放空间
	delete ptr1;
	delete ptr2;
	delete[] ptr3;
}

注意:

申请和释放单个元素的空间,使用 new 和 delete 操作符,申请和释放连续的空间,使用 new[] 和 delete[],匹配使用!

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

Stack 的构造和析构:

typedef char DataType;
class Stack
{
public:
	Stack(int capacity = 4)
	{
		cout << "Stack()" << endl;

		_array = new DataType[4];
		_capacity = capacity;
		_size = 0;
	}
	void Push(DataType data)
	{
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;

		delete[] _array;
		_array = nullptr;
		_capacity = _size = 0;
	}
private:
	// 内置类型
	DataType* _array;
	int _capacity;
	int _size;
};

Stack* func()
{
	int n;
	cin >> n;

	Stack* pst = new Stack(n);
	return pst;
}

int main()
{
	Stack* ptr = func();
	ptr->Push(1);
	ptr->Push(2);

	delete ptr;
	return 0;
}

4、operator new与operator delete函数

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

operator new 实际也是通过 malloc 来申请空间,如果 malloc 申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过 free 来释放空间的。

5、new和delete的实现原理

5.1 内置类型

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

5.2 自定义类型

new 的原理

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

delete 的原理

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

new T[N] 的原理

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

delete[] 的原理

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

6、面试题

6.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 在释放空间前会调用析构函数完成空间中资源的清理

6.2 内存泄漏

内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Axure PR 9 开关切换 设计交互

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来探讨Axure开关按钮设计与交互技巧​。 创建切换开关所需的元件 1.打开一个新的 RP 文件并在画布上打开 Page 1。 2.将“圆形”元件拖到画布上&#xff0c;在样式窗格中将高度和宽度设置为35&#xff0c;线段宽度…

[贪心+搜索] 马走日升级版

题目描述 国际象棋和中国象棋中&#xff0c;马的移动规则相同&#xff0c;都是走“日”字&#xff0c;我们将这种移动方式称为马步移动。如右图所示&#xff0c;从标号为 0 0 0 的点出发&#xff0c;可以经过一步马步移动达到标号为 1 1 1 的点&#xff0c;经过两步马步移动…

Excel中的常识

工作簿Workbook和工作表Worksheet什么关系&#xff1f; 工作簿&#xff1a;Workbook&#xff0c;也就是一个excel文件 工作表&#xff1a;Worksheet&#xff0c;也就是一个工作表&#xff0c;及Sheet文件 一个工作簿可以包含多个工作表。

IDM(Internet Download Manager)下载器的安装激活与换机方法

很多人都知道 Internet Download Manager(以下简称 IDM)是一款非常优秀的下载提速软件。它功能强大&#xff0c;几乎能下载网页中的所有数据&#xff08;包括视频、音频、图片等&#xff09;&#xff0c;且适用于现在市面上几乎所有的浏览器&#xff0c;非常受大家欢迎。IDM 是…

vue-插槽作用域实用场景

vue-插槽作用域实用场景 1.插槽1.1 自定义列表渲染1.2 数据表格组件1.3 树形组件1.4 表单验证组件1.5 无限滚动组件 1.插槽 插槽感觉知道有这个东西&#xff0c;但是挺少用过的&#xff0c;每次看到基本都会再去看一遍用法和概念。但是在项目里&#xff0c;自己还是没有用到过…

QD1-P1 开始学习前端,HTML、CSS与JS三者之间的关系

今天开始学习前端基础&#xff0c;新建专题《前端学习笔记1》保存前端基础学习笔记。 专题文章命名以qd1开头。 源课程 视频教程&#xff1a;【Web前端-最通俗易懂HTML、CSS与JS合集 1天速成】 up&#xff1a;遥遥温柔乡 在B站随便搜索了一个前端课程&#xff0c;共91节&am…

JVS低代码轻应用是什么?是如何拼装的?这篇文章讲的非常详细

1.1JVS轻应用是什么&#xff1f; 轻应用与传统应用的开发过程区别 传统开发&#xff08;原生开发&#xff09;采用的方式&#xff1a;①需求了解 ②产品原型③UI设计④建库建表⑤前端还原⑥后端开发⑦前后端联调⑧功能测试⑨部署上线轻应用开发方式&#xff08;配置化拼装&…

SpringBoot定时任务@Scheduled完整功能详解(提供Gitee源码)

目录 一、实现定时任务 1.1、fixedRate 1.2、fixedDelay 1.3、initialDelay 1.4、cron 二、cron表达式 三、读取配置文件 四、实现并行执行定时任务 五、Gitee源码 一、实现定时任务 首先在主应用类或者任何配置类上添加@EnableScheduling注解,以启用定时任务功能。…

基于monaco-editor的web日志组件

基于monaco-editor封装的编辑器&#xff0c;支持如下功能&#xff1a; 日志内容颜色配置&#xff1a;info、primary、success、warning、error支持主题配置&#xff1a;dark、light支持滚动到顶部、底部、全屏编辑器默认带的全局搜索扩展性强&#xff0c;支持monaco的所有配置…

STM32学习--4-1 OLED显示屏

接线图 OLED.c #include "stm32f10x.h" #include "OLED_Font.h"/*引脚配置*/ #define OLED_W_SCL(x) GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x)) #define OLED_W_SDA(x) GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))/*引脚初始化*/ void …

selenium:WebElement类的核心操作方法(3)

当我们通过webdriver中的find_element函数定位到元素后&#xff0c;其实返回的是WebElement对象&#xff0c;而该对象有很多重要的方法&#xff0c;比如输入文本&#xff0c;点击按钮&#xff0c;获取属性&#xff0c;截屏等 WebElement类的方法介绍 文本输入与清除 send_key…

【原创教程】电气电工23:电气柜的品牌及常用型号

电气电工要清楚常用的电气柜品牌及型号,对于电器柜的选择,现在我们一般常用的品牌有3个。分别是好夫满、上海上海桐赛电气和南京巴哈曼电气,还有一种就是网上订制。 一、好夫满系列电气箱 好夫满有很多种类的机箱,EB精巧控制箱系列、KL接线箱系列、BKL不锈钢接线箱系列、…

构建基于 阻塞队列 / 环形队列 的高效生产消费者模型系统

1. 生产者-消费者问题 概述 生产-消费者模型 &#xff1a;一个或多个 生产者线程 产生数据并将其放入共享缓冲区&#xff0c;同时一个或多个 消费者线程 从该缓冲区中读取数据进行操作的情景。 缓冲区 是一个用于存储生产者产生数据的中间容器&#xff1b;缓冲区 的容量通常是…

【操作系统】四、文件管理:1.文件系统基础(文件属性、文件逻辑结构、文件物理结构、文件存储管理、文件目录、基本操作、文件共享、文件保护)

文件管理 文章目录 文件管理八、文件系统基础1.文件的属性2.文件的逻辑结构2.1顺序文件2.2索引文件2.3索引顺序文件2.4多级索引顺序文件 3.目录文件❗3.1文件控制块FCB3.1.1对目录进行的操作 3.2目录结构3.2.1单级目录结构3.2.2两级目录结构3.2.3多级目录结构&#xff08;树形目…

vue2引入i18n插件实现中英文切换

vue2引入i18n插件实现中英文切换 1.安装i18n插件2.引入3.使用4.数据渲染 1.安装i18n插件 npm install vue-i18n --save-dev注意&#xff1a; vue2环境下安装i18n插件时 有可能会报错&#xff08;我的这个项目比较老&#xff0c;vue2.5.x版本的&#xff09;&#xff0c;报错信息…

保姆级教程 | Linux中grep命令使用 分子动力学轨迹文件输出特定原子电荷值

背景 由于课题需要&#xff0c;现根据lammps运行得到的轨迹需要提取出目标原子的电荷值 步骤 思路 首先确定目标原子在轨迹中的序号&#xff08;lammps每个原子都有自己独立的【分子号原子号】&#xff09; 其次要十分清楚体系中的分子号排序方式&#xff0c;然后只要筛选出…

安卓13禁止锁屏 关闭锁屏 android13禁止锁屏 关闭锁屏

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 设置 =》安全 =》屏幕锁定 =》 无。 我们通过修改系统屏幕锁定配置,来达到设置屏幕不锁屏的配置。像网上好多文章都只写了在哪里改,改什么东西,但是实际上并未写明为什么要改那…

浅谈虚拟电厂在分布式光伏发电应用示范区中的应用及前景

0引言 随着电力体制改革的持续推进&#xff0c;电力市场将逐步建立和完善&#xff0c;未来的售电主体也将随着配售电业务的逐步放开而日益多元化&#xff0c;新的政策不断鼓励分布式电源和微电网作为独立的配售电市场主体推动运营模式的创新。与微电网所采取的就地应用为控制目…

离散数学-逻辑与证明基础1.4(谓词和量词)

谓词 1.4.2 谓词 涉及变量的语句&#xff0c;例如&#xff1a; “ x > 3 x > 3 x>3”&#xff0c;“ x y 3 x y 3 xy3”&#xff0c;“ x y z x y z xyz” 以及 \quad “Computer x x x is under attack by an intruder” \quad “Computer x x x is f…

nginx虚拟主机配置与locaion规则

目录 1.虚拟主机 1.1分类 1.2基于域名的虚拟机 1.2.1测试 1.3基于端口的虚拟主机 1.3.1测试 ​编辑1.4基于IP的虚拟主机 2.nginx日志 3.location 1.虚拟主机 虚拟主机:相当于1个网站&#xff0c;在nginx中通过server{}区域实现。 nginx虚拟主机有不同的配置类型…