【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 在 B2. 填空题:
sizeof(num1) = 40;
sizeof(char2) = 5; 注意 sizeof 计算时包括最后的'\0'
strlen(char2) = 4;//遇到'\0'终止
sizeof(pChar3) = 4/8;
strlen(pChar3) = 4;
sizeof(ptr1) = 4/8;

【说明】
- 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 堆用于程序运行时动态内存分配,堆是向上增长的。
- 数据段--存储全局数据和静态数据。
- 代码段--可执行的代码/只读常量。
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 的原理
- 调用 operator new 函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
delete 的原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用 operator delete 函数释放对象的空间
new T[N] 的原理
- 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对象空间的申请
- 在申请的空间上执行 N 次构造函数
delete[] 的原理
- 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理
- 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间
6、面试题
6.1 malloc/free和new/delete的区别
malloc/free 和 new/delete 的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:
- malloc 和 free 是函数,new 和 delete是操作符
- malloc 申请的空间不会初始化,new 可以初始化
- malloc 申请空间时,需要手动计算空间大小并传递,new 只需在其后跟上空间的类型即可,如果是多个对象,[] 中指定对象个数即可
- malloc 的返回值为 void*,在使用时必须强转,new 不需要,因为 new 后跟的是空间的类型
- malloc 申请空间失败时,返回的是 NULL,因此使用时必须判空,new 不需要,但是 new 需要捕获异常
- 申请自定义类型对象时,malloc/free 只会开辟空间,不会调用构造函数与析构函数,而 new在申请空间后会调用构造函数完成对象的初始化,delete 在释放空间前会调用析构函数完成空间中资源的清理
6.2 内存泄漏
内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。
相关文章:
【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(s…...
【Java SE】方法 和 递归 的应用
🔥博客主页🔥:【 坊钰_CSDN博客 】 欢迎各位点赞👍评论✍收藏⭐ 目录 1. 方法的含义 1.1 例子 1.2 方法的概念 2. 方法的定义 3. 实参和形参 3.1 实参和形参的关系 4. 方法的重载 5. 递归 5.1 递归练习 6. 小结 1. 方法的…...
JVS低代码轻应用是什么?是如何拼装的?这篇文章讲的非常详细
1.1JVS轻应用是什么? 轻应用与传统应用的开发过程区别 传统开发(原生开发)采用的方式:①需求了解 ②产品原型③UI设计④建库建表⑤前端还原⑥后端开发⑦前后端联调⑧功能测试⑨部署上线轻应用开发方式(配置化拼装&…...
K210(openMV)与STM32 通信教程
目录 前言: 一、K210 串口部分教程 二、STM32部分 前言: 很多打比赛的同学,通常只是用K210 或者openMV来进行视觉部分的信息采集,传输数据给STM32(或者其他主控那边)进行对分析,对小车或者舵…...
【HarmonyOS】HMRouter使用详解(三)生命周期
生命周期(Lifecycle) 使用HMRouter的页面跳转时,想实现和Navigation一样的生命周期时,需要通过新建生命周期类来实现对页面对某一个生命周期的监控。 新建Lifecycle类 通过继承IHMLifecycle接口实现生命周期接口的方法重写。 通过…...
Docker 教程三 (Ubuntu Docker安装)
Ubuntu Docker 安装 Docker Engine-Community 支持以下的 Ubuntu 版本: Xenial 16.04 (LTS)Bionic 18.04 (LTS)Cosmic 18.10Disco 19.04 其他更新的版本…… Docker Engine - Community 支持上 x86_64(或 amd64)armhf,arm64&am…...
Redis:持久化
Redis:持久化 持久化RDBdump.rdb优缺点 AOF文件同步重写机制 混合持久化 持久化 虽然Redis是一个内存级别的数据库,但是Redis也是有持久化的能力的。当系统崩溃时,Redis就会被强制退出,此时内存中的数据就会丢失。为了能够在下次…...
精准监控,高效运营 —— 商品信息实时分析为商家带来新机遇
在现代商业环境中,精准监控和高效运营是商家成功的关键。通过实时分析商品信息,商家可以洞察市场趋势、优化库存管理、提升销售策略,从而抓住新的商业机遇。本文将介绍如何利用Python和一些流行的数据分析工具来实现商品信息的实时分析&#…...
Nginx应用配置实战
Nginx通用部署 Nginx常见参数介绍 Nginx 配置文件中的指令和参数决定了它的行为。下面详细介绍一些常见的 Nginx 参数,以帮助你更好地理解和配置 Nginx。 1. worker_processes worker_processes auto;作用:设置 Nginx 处理请求的工作进程数量。auto …...
html实现倒计时
参考网址 <!DOCTYPE html> <html> <head><title>倒计时示例</title> </head> <body><h1 id"titleCountDown"></h1><div id"countdown"></div><script>// 目标日期var targetDat…...
HTMLCSS练习
1) 效果如下 2) 代码如下 2.1) HTML <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conte…...
LeetCode讲解篇之377. 组合总和 Ⅳ
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 总和为target的元素组合个数 可以由 总和为target - nums[j]的元素组合个数 转换而来,其中j为nums所有元素的下标 而总和target - nums[j]的元素组合个数 可以由 总和为target - nums[j] - nums[k]的…...
Midjourney中文版:创意无限,艺术之旅由此启程
Midjourney中文版——一个将你的文字想象转化为视觉艺术的神奇平台。无需繁琐的绘画技巧,只需简单的文字描述,你就能开启一场前所未有的艺术之旅。 Midjourney AI超强绘画 (原生态系统)用户端:Ai Loadinghttps://www.mjdiscord.c…...
安装R和RStudio:开始你的数据分析之旅
数据分析是当今世界中一个非常热门的领域,而R语言是进行数据分析的强大工具之一。R是一种编程语言和软件环境,用于统计计算和图形表示。RStudio是一个集成开发环境(IDE),它为R语言提供了一个更加友好和高效的工作环境。…...
如何使用python连接数据库?
数据分析离不开数据库,如何使用python连接数据库呢?听我娓娓道来哈 该笔记参考了PyMySQL官方文档和《python数据采集》关于数据存储的部分,欢迎大家去阅读原著,相信会理解的更加透彻。 补充:文末增加Oracle数据库的连…...
停车位识别数据集 图片数量12416张YOLO,xml和txt标签都有; 2类类别:space-empty,space-occupied;
YOLO停车位识别 图片数量12416张,xml和txt标签都有; 2类类别:space-empty,space-occupied; 用于yolo,Python,目标检测,机器学习,人工智能,深度学习࿰…...
MySQL 创建子账号
1. 使用 root 账号登录 MySQL 使用 root 账号登录 MySQL,登录成功如图所示: 新建一个 MySQL 子账号,新建子账号命令如下: 命令 : CREATE USER testlocalhost IDENTIFIED BY 123456;若出现如下图所示,则表示新建 MySQL…...
代码随想录 106. 岛屿的周长
106. 岛屿的周长 #include<bits/stdc.h> using namespace std;int main(){int n, m;cin >> n >> m;vector<vector<int>> mp(n, vector<int>(m, 0));for (int i 0; i < n; i){for (int j 0; j < m; j){cin >> mp[i][j];}}in…...
阿里云融合认证中的App端一键登录能力
在如今的移动互联网环境中,App端的一键登录功能逐渐成为提升用户体验的关键。用户不再需要繁琐的注册流程或输入短信验证码,一键即可通过手机号码完成登录。而阿里云融合认证中,一键登录能力为移动应用提供了一个简单、便捷且安全的用户身份验…...
基于YOLO11/v10/v8/v5深度学习的安检X光危险品检测与识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
告别迷茫!Quartus II 13.1 从新建工程到烧录FPGA的保姆级避坑指南
Quartus II 13.1实战指南:从零开始玩转FPGA开发 第一次打开Quartus II 13.1时,那个灰蒙蒙的界面和密密麻麻的菜单栏确实容易让人望而生畏。作为Altera(现已被Intel收购)旗下经典的FPGA开发工具,它在高校实验室和企业研…...
从草图到逼真人脸:Qwen-Image-Edit-F2P结合ControlNet的进阶玩法展示
从草图到逼真人脸:Qwen-Image-Edit-F2P结合ControlNet的进阶玩法展示 最近在玩AI图像生成的朋友,可能都遇到过这样的烦恼:想让AI画一张特定角度、特定表情的人脸,光靠文字描述,结果总是像开盲盒。你说“一个微笑的东方…...
Java车载HMI卡顿问题终极解析,GPU渲染线程阻塞+Binder调用链路断点调试(附AS+ADB定制脚本)
第一章:Java车载HMI卡顿问题的系统性认知车载人机交互界面(HMI)作为智能座舱的核心入口,其响应流畅度直接影响用户安全与体验。当基于Java(如Android Automotive OS或定制JVM嵌入式框架)构建的HMI出现卡顿&…...
StructBERT语义分析工具实测:一键判断句子相似度,支持GPU加速
StructBERT语义分析工具实测:一键判断句子相似度,支持GPU加速 1. 工具核心价值 StructBERT语义分析工具是一款专为中文文本设计的本地化语义相似度计算解决方案。不同于传统的关键词匹配方法,该工具基于阿里巴巴开源的StructBERT-Large模型…...
InvokeAI工具函数库:10个核心工具方法与实用辅助函数详解
InvokeAI工具函数库:10个核心工具方法与实用辅助函数详解 【免费下载链接】InvokeAI Invoke is a leading creative engine for Stable Diffusion models, empowering professionals, artists, and enthusiasts to generate and create visual media using the late…...
Pixel Couplet Gen基础教程:Streamlit+ModelScope零配置环境搭建步骤详解
Pixel Couplet Gen基础教程:StreamlitModelScope零配置环境搭建步骤详解 1. 项目介绍与准备 Pixel Couplet Gen是一款融合了传统春节文化与现代像素艺术风格的AI春联生成器。它基于ModelScope大模型驱动,通过Streamlit构建了独特的8-bit复古游戏界面&a…...
第二桌面 + 小龙虾:让企业AI智能体安全落地、全员可用
本文发布于2026年4月1日。引言:从“养虾”到“用虾”,AI落地需要新底座过去几个月,OpenClaw(昵称“小龙虾”)在开发者圈子里火得一塌糊涂。这个开源AI智能体网关,能听懂人话,还能替你操作电脑、…...
4步攻克Fiji在macOS系统的启动难题:从诊断到长效维护的全方位解决方案
4步攻克Fiji在macOS系统的启动难题:从诊断到长效维护的全方位解决方案 【免费下载链接】fiji A "batteries-included" distribution of ImageJ :battery: 项目地址: https://gitcode.com/gh_mirrors/fi/fiji 问题定位:精准识别Fiji启动…...
intv_ai_mk11生成效果:对‘提高工作效率’需求输出结构清晰、可执行的5条建议
intv_ai_mk11生成效果:对"提高工作效率"需求输出结构清晰、可执行的5条建议 1. 模型介绍与使用场景 intv_ai_mk11是一个基于Llama架构的中等规模文本生成模型,特别适合处理通用问答、文本改写、解释说明等任务。这个模型已经完成本地部署&am…...
Infinity Pro书签迁移终极指南:从JSON文件到本地缓存的完整操作流程
Infinity Pro书签迁移终极指南:从JSON文件到本地缓存的完整操作流程 作为一名长期使用Infinity Pro的开发者,我深知书签迁移的痛点。每次换设备或重装系统,那些精心整理的技术资源库都要重新配置。本文将分享一套经过实战验证的迁移方案&…...
