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

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类型的空间并初始化为10int* 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.mzph.cn/diannao/55966.shtml

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

相关文章

与C++内存管理和STL简介的爱恨情仇

本文 1.C/C内存分布2.C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free总结 3.C内存管理方式new/delete操作内置类型new和delete操作自定义类型 4.operator new与operator delete函数&#xff08;重要点进行讲解&#xff09;5.new和delete的实现原理内置类型自定…

制造业DT数字化之生产制造业务建模

一、工厂建模为何物&#xff1f; 对制造业人员&#xff08;人&#xff09;、设备&#xff08;机&#xff09;、材料&#xff08;料&#xff09;、工艺流程&#xff08;法&#xff09;、工厂环境&#xff08;环&#xff09;数据化管理的过程就叫工厂建模。 二、制造建模有哪几大…

【操作系统】引导(Boot)电脑的奇妙开机过程

&#x1f339;&#x1f60a;&#x1f339;博客主页&#xff1a;【Hello_shuoCSDN博客】 ✨操作系统详见 【操作系统专项】 ✨C语言知识详见&#xff1a;【C语言专项】 目录 什么是操作系统的引导&#xff1f; 操作系统的引导&#xff08;开机过程&#xff09; Windows操作系…

QD1-P2 HTML 编辑器:HBuilderX

本节学习&#xff1a; HTML课程内容介绍HBuilderX编辑器的使用 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p2 HTML 内容 基础语法 标签整体架构DOCTYPE 常用标签 标题和水平线段落和换行列表div 和 span格式化标签图片超链接标签表格表单字符实体 编辑器 HBuilder…

设计测试用例的方法

目录 1、等价类 2、边界值 3、场景法 4、正交表法 5、设计正交表 6、判定表法 7、错误猜想法 1、等价类 在测试中选取一些数据作为等价类进行测试&#xff0c;如果测试通过&#xff0c;就代表测试通过&#xff0c;可以用少量代表性的测试数据取得较好的测试结果。 等价类…

智能扭矩系统在轨道交通行业的应用_SunTorque

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 在现代轨道交通领域&#xff0c;安全、高效和可靠性是至关重要的考量因素。智能扭矩系统作为一项先进的技术&#xff0c;正逐渐在轨道交通行业中展现出其重要的应用…

【原创】java+springboot+mysql劳动教育网系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

使用Milvus和Llama-agents构建更强大的Agent系统

代理&#xff08;Agent&#xff09;系统能够帮助开发人员创建智能的自主系统&#xff0c;因此变得越来越流行。大语言模型&#xff08;LLM&#xff09;能够遵循各种指令&#xff0c;是管理 Agent 的理想选择&#xff0c;在许多场景中帮助我们尽可能减少人工干预、处理更多复杂任…

C++与Java Web开发的对比分析:优势与差异

目录 1. 引言 2. C的开发优势与特点 2.1 高性能与硬件控制 2.2 面向对象与多范式支持 2.3 跨平台能力 3. Java Web的开发优势与特点 3.1 跨平台与广泛的企业应用 3.2 丰富的生态系统与工具支持 3.3 安全性与稳定性 4. C与Java Web的差异对比 4.1 性能与效率 4.2 开发…

基于go开发的终端版即时通信系统(c-s架构)

项目架构图 类似一个聊天室一样 整体是一个客户端和服务端之间的并发多线程网络通信&#xff0c;效果可以翻到最后面看。 为了巩固基础的项目练手所以分为9个阶段进行迭代开发 版本⼀&#xff1a;构建基础Server 新建一个文件夹就叫golang-IM_system 第一阶段先将server的大…

LLM | Tokenization 从原理与代码了解GPT的分词器

声明&#xff1a;以上内容全是学习Andrej Karpathy油管教学视频的总结。 --------------------------------------------------------------------------------------------------------------------------------- 大家好。在今天我们学习llm中的Tokenization&#xff0c;即分…

使离医院最远的村庄到医院的路程最短

给定n个村庄之间的交通图&#xff0c;若村庄i和j之间有道路&#xff0c;则将顶点i和j用边连接&#xff0c;边上的Wij表示这条道路的长度&#xff0c;现在要从这n个村庄中选择一个村庄建一所医院&#xff0c;问这所医院应建在哪个村庄&#xff0c;才能使离医院最远的村庄到医院的…

HCIP--以太网交换安全(三)MAC地址漂移防止与检测

MAC地址漂移防止与检测 一、MAC地址漂移防止与检测知识点 1.1MAC地址漂移的概述 MAC地址漂移是指交换机上一个vlan内有两个端口学习到同一个MAC地址&#xff0c;后学习到的MAC地址表项覆盖原MAC地址表项的现象。 1.2.MAC地址漂移的防止方法 &#xff08;1&#xff09;配置…

Windows7 X64 成功安装 .NET Framework 4.8 的两种方法

Windows7 X64 成功安装 .NET Framework 4.8 的两种方法 windows7系统SP1安装完成后&#xff0c;在安装某软件时&#xff0c;提示需要先安装4.6以上的版本net-framework包&#xff0c;正好电脑里有个net-framework4.8软件包&#xff0c;于是打算用上&#xff0c;可是在安装时&a…

Github 2024-10-11 Java开源项目日报 Top9

根据Github Trendings的统计,今日(2024-10-11统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Java项目9TypeScript项目1Vue项目1C++项目1JeecgBoot 企业级低代码开发平台 创建周期:2062 天开发语言:Java, Vue协议类型:Apache License 2.…

LabVIEW激光诱导击穿光谱识别与分析系统

LabVIEW激光诱导击穿光谱&#xff08;LIBS&#xff09;分析系统利用高能量脉冲激光产生高温等离子体&#xff0c;通过分析等离子体发出的光谱来定性分析样品中的元素种类。该系统的开发集成了软件与硬件的设计&#xff0c;实现了自动识别和定性分析功能&#xff0c;适用于环境监…

OpenCV 之 实现基于Lucas-Kanade算法的光流追踪

引言 在计算机视觉中&#xff0c;光流是指物体、场景或摄像机之间的相对运动造成的像素变化。光流估计是计算机视觉中的一个基础课题&#xff0c;广泛应用于许多领域&#xff0c;比如自动驾驶汽车、机器人导航、手势识别等。OpenCV是一个开源的计算机视觉库&#xff0c;提供了…

计算机网络:计算机网络概述 —— 描述计算机网络的参数

文章目录 数据量性能指标速率带宽数据传输速率 吞吐量时延分析时延问题 时延带宽积往返时间利用率丢包率丢包的情况 抖动可用性可靠性安全性 计算机网络是现代信息社会的基础设施&#xff0c;其性能和可靠性对各类应用至关重要。为了理解和优化计算机网络&#xff0c;我们需要深…

vue后台管理系统从0到1(1)

文章目录 vue后台管理系统从0到1&#xff08;1&#xff09;nvm 下载安装1.卸载nodejs环境2.安装nvm 安装nrm vue后台管理系统从0到1&#xff08;1&#xff09; 第一节主要是先安装我们的工具nvm nodejs版本管理工具&#xff0c;和nrm镜像管理工具 nvm 下载安装 nvm是一款管理…

重学SpringBoot3-集成Redis(一)之基础功能

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;一&#xff09;之基础功能 1. 项目初始化2. 配置 Redis3. 配置 Redis 序列化4. 操作 Redis 工具类5. 编写 REST 控制器6. 测试 AP…