C++的内存管理
内存分布高地址 ↑ ├─────────────┤ │ 栈 │ ← 向下增长局部变量、函数参数 ├─────────────┤ │ │ │ │ ↓ │ ├─────────────┤ │ 内存映射段 │ ← 共享库、共享内存 ├─────────────┤ │ ↑ │ │ │ │ ├─────────────┤ │ 堆 │ ← 向上增长动态分配 ├─────────────┤ │ 数据段 │ ← 全局变量、静态变量 ├─────────────┤ │ 代码段 │ ← 可执行代码、常量 └─────────────┘ 低地址 includeiostream using namespace std; 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); // 注意ptr2被realloc处理了不需要再free } int main() { Test(); return 0; }说明栈又叫做堆栈——存储非静态局部变量/函数参数/返回值等向下增长内存映射段是高效的I/O映射方式用于装载一个共享的动态内存库。堆是用于内存的动态内存分配向上增长系统一般给的内存都比较大数据段用于存储全局变量和静态变量代码段用于可执行的代码/只读常量动态内存管理malooc/calloc/realloc的区别#includeiostream using namespace std; void Test() { // 1. malloc - 分配未初始化的内存 int* p1 (int*)malloc(sizeof(int) * 4); if (p1 NULL) { perror(malloc fail); return; } // 2. calloc - 分配并初始化为0 int* p2 (int*)calloc(4, sizeof(int)); // calloc(4, sizeof(int)) 等价于 malloc(4 * sizeof(int)) 内存置0 // 3. realloc - 调整已分配内存的大小 int* p3 (int*)realloc(p2, sizeof(int) * 10); // 注意如果realloc成功p2会被自动处理不需要free(p2) if (p3 NULL) { free(p2); // realloc失败时原内存不变需要手动释放 return; } // 释放内存 free(p1); free(p3); // p2已经被realloc处理不需要单独free }内存管理方式C语言的内存管理方式在C也可以使用但是也有一些欠缺点用起来比较麻烦。因此C有自己新的内存管理方式——通过操作符new和delete用法讲解#includeiostream using namespace std; int main() { // 1. 基本用法申请和释放单个对象 int* p1 new int; // 申请一个 int未初始化 int* p2 new int[10]; // 申请 10 个 int 的数组未初始化 delete p1; // 释放单个对象 delete[] p2; // 释放数组 // 2. 初始化用法申请时初始化 int* p3 new int(0); // 申请一个 int初始化为 0 int* p4 new int[10]{ 0 }; // 申请 10 个 int全部初始化为 0 int* p5 new int[10]{ 1, 2, 3, 4, 5 }; // 前5个初始化后面默认为0 delete p3; // 释放单个对象 delete[] p4; // 释放数组 delete[] p5; // 释放数组 return 0; }注意new 和 delete 必须配对使用new - deletenew[] - delete []应用示例struct ListNode { int val; ListNode* next; ListNode(int x) : val(x) , next(nullptr) {} }; int main() { // 1. 自定义类型 A 的 new/delete假设 A 存在 // A* p1 new A; // 调用默认构造 // A* p2 new A(1); // 调用带参构造 // delete p1; // delete p2; // 2. 创建链表节点 ListNode* n1 new ListNode(1); ListNode* n2 new ListNode(2); ListNode* n3 new ListNode(3); ListNode* n4 new ListNode(4); // 3. 连接节点形成链表 n1-next n2; n2-next n3; n3-next n4; n4-next nullptr; // 尾节点指向 nullptr已经由构造函数设置 // 4. 遍历链表 ListNode* cur n1; while (cur ! nullptr) { cout cur-val - ; cur cur-next; } cout nullptr endl; // 5. 释放链表内存重要 cur n1; while (cur ! nullptr) { ListNode* next cur-next; // 保存下一个节点 delete cur; // 释放当前节点 cur next; // 移动到下一个 } return 0; }可以看到写链表的时候可以直接传参初始化不需要写Init。从应用层面我们可以看到创造new和delete的原因是为了给自定义类型使用的因为自定义类型往往都需要调用默认构造函数更为方便对应内置类型和malloc和free的区别不大自定义类型int main() { // 1. 单个对象使用 new 申请并构造 A* p1 new A(1); // 调用 A(int) 构造函数 A* p2 new A(2, 2); // 调用 A(int, int) 构造函数 // 2. 对象数组使用已有对象拷贝构造 A aa1(1, 1); A aa2(2, 2); A aa3(3, 3); A* p3 new A[3]{ aa1, aa2, aa3 }; // 调用拷贝构造 // 3. 对象数组使用临时对象 A* p4 new A[3]{ A(1, 1), A(2, 2), A(3, 3) }; // 4. 对象数组使用聚合初始化C11 列表初始化 A* p5 new A[3]{ {1, 1}, {2, 2}, {3, 3} }; // 释放内存 delete p1; delete p2; delete[] p3; delete[] p4; delete[] p5; return 0; }具体用法详解对单个对象class A { public: A(int x) : _a(x) { cout A(int) 构造 endl; } A(int x, int y) : _a(x), _b(y) { cout A(int,int) 构造 endl; } ~A() { cout ~A() 析构 endl; } private: int _a; int _b; }; int main() { // 1. 单个对象调用构造函数 A* p1 new A(10); // 调用 A(int) A* p2 new A(20, 30); // 调用 A(int, int) // 2. 释放单个对象调用析构函数 delete p1; // 先调用 ~A()再释放内存 delete p2; return 0; }对象数组int main() { // 方式1默认构造需要 A 有默认构造 A* p1 new A[3]; // 调用 3 次默认构造 // 方式2使用已有对象拷贝构造 A a1(1, 1), a2(2, 2), a3(3, 3); A* p2 new A[3]{ a1, a2, a3 }; // 调用 3 次拷贝构造 // 方式3使用临时对象 A* p3 new A[3]{ A(1, 1), A(2, 2), A(3, 3) }; // 方式4列表初始化C11 A* p4 new A[3]{ {1, 1}, {2, 2}, {3, 3} }; // 释放数组必须用 delete[] delete[] p1; // 先调用 3 次析构再释放内存 delete[] p2; delete[] p3; delete[] p4; return 0; }关键点——new和delete的底层调用的是operatror new和operator deletenew的执行过程A* p new A(1, 2); // 执行步骤 // 1. 调用 operator new 分配内存类似 malloc // 2. 在分配的内存上调用 A 的构造函数 // 3. 返回指向该对象的指针 new A(1, 2) │ ├─ 1. 调用 operator new (全局函数) │ │ │ └─ 调用 malloc() 分配原始内存 │ │ │ ├─ 成功 → 返回内存地址 │ └─ 失败 → 执行用户设置的应对措施 │ └─ 仍失败 → 抛出 bad_alloc 异常 │ ├─ 2. 在分配的内存上调用 A 的构造函数 │ └─ A::A(1, 2) 初始化对象 │ └─ 3. 返回指向构造完成的对象的指针delete的执行过程delete p; // 执行步骤 // 1. 调用 p 指向对象的析构函数 // 2. 调用 operator delete 释放内存类似 free delete p │ ├─ 1. 调用 p 指向对象的析构函数 │ └─ A::~A() 清理对象资源 │ └─ 2. 调用 operator delete (全局函数) │ └─ 调用 free() 释放原始内存new[]和delete[]的执行过程A* p new A[3]{ A(1,1), A(2,2), A(3,3) }; // 执行步骤 // 1. 分配能容纳 3 个 A 对象的内存 额外空间存储数组大小 // 2. 按顺序调用 3 次构造函数 delete[] p; // 执行步骤 // 1. 按逆序调用 3 次析构函数先析构最后一个 // 2. 释放内存注意事项new和delete的配对// 错误 A* p1 new A(1); delete[] p1; // 错误单个对象不能用 delete[] A* p2 new A[3]; delete p2; // 错误数组必须用 delete[] // 正确 A* p1 new A(1); delete p1; A* p2 new A[3]; delete[] p2;自定义类型必须要有正确的构造函数class B { public: B(int x) : _x(x) {} // 只有带参构造没有默认构造 private: int _x; }; int main() { B* p1 new B(10); // 可以 // B* p2 new B; // 错误没有默认构造 // B* p3 new B[3]; // 错误数组需要默认构造 delete p1; return 0; }内存泄漏问题/ 内存泄漏 void BadFunction() { A* p new A(1); // 没有 delete p函数结束导致内存泄漏 } // 正确 void GoodFunction() { A* p new A(1); delete p; } // 更好使用智能指针 #includememory void BestFunction() { unique_ptrA p make_uniqueA(1); // 自动释放 }关于operator new 和 operator deletevoid* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { void* p; // 尝试分配内存 while ((p malloc(size)) 0) { // 如果分配失败执行用户设置的 new_handler if (_callnewh(size) 0) { // 用户没有设置应对措施或措施失败抛出异常 static const std::bad_alloc nomem; _RAISE(nomem); } } return p; } void operator delete(void* pUserData) { if (pUserData NULL) return; // 直接调用 free 释放内存 free(pUserData); }核心newoperator new分配内存构造函数delete析构函数operator delete释放内存new[]operator new[]分配内存N次构造函数delete[]N次析构函数operator delete[]释放内存

相关新闻

C++ Boost.Beast 自定义 Body:零拷贝与流式处理

C++ Boost.Beast 自定义 Body:零拷贝与流式处理

本文深入 Boost.Beast 的 Body 体系,讲解 BodyReader/BodyWriter 概念要求,实现一个自定义 Body,并详解 http::buffer_body 的零拷贝流式用法。所有 API 均对照 Beast 官方文档与头文件源码核实。 这是 Boost.Beat 系列的最难一篇,涉及 Beast 的核心扩展机制。 一、为什么需…

2026/10/16 21:21:15 阅读更多 →
架构设计之Redisson分布式锁-自定义大注解(十)

架构设计之Redisson分布式锁-自定义大注解(十)

摘要:本文是架构设计系列第十篇,深入剖析 Redisson 分布式锁的核心原理与实战开发。我们将从基础概念出发,逐步讲解 Redisson 的锁机制、WatchDog 自动续期、可重入锁、公平锁、联锁、红锁等高级特性,并重点实现一套基于自定义注解…

2026/10/18 8:47:13 阅读更多 →
拆解 OpenStack 虚拟网络!Neutron 底层原理 + OVN 组网实操

拆解 OpenStack 虚拟网络!Neutron 底层原理 + OVN 组网实操

OpenStack管理 摘要:本文系统介绍了OpenStack网络管理组件Neutron的核心原理与实践。首先对比物理网络与虚拟网络,阐述Neutron对二层物理网络的抽象与管理。接着详细讲解Linux网络虚拟化关键技术,包括网卡虚拟化(TAP/TUN/VETH&…

2026/10/17 6:27:41 阅读更多 →

最新新闻

PP-DocLayoutV3版面分析实战:从RAG乱序到结构化文档预处理

PP-DocLayoutV3版面分析实战:从RAG乱序到结构化文档预处理

前阵子在帮某技术团队做企业内部知识库的问答系统,天天和一批扫描版PDF打交道。系统整体跑通之后,检索质量一直上不去,答非所问的情况特别多。排查到最后,问题指向的不是向量模型,也不是检索策略,而是最基础…

2026/10/19 4:50:03 阅读更多 →
HDFS生产级深度解析:架构本质、配置陷阱与可观测运维

HDFS生产级深度解析:架构本质、配置陷阱与可观测运维

1. 项目概述:从“离线Day03”看HDFS在真实数据工程中的定位你打开一份名为“hadoop离线day03--Hadoop HDFS”的课程材料或笔记标题,第一反应可能是:“哦,又一节Hadoop基础课”。但如果你真在某公司数据平台组干过两年以上&#xf…

2026/10/19 4:50:02 阅读更多 →
AutoGen 10.1实战:多Agent对话协作框架全面拆解

AutoGen 10.1实战:多Agent对话协作框架全面拆解

“10.1”这个版本号一出来,熟悉的朋友应该知道我说的是哪个东西——AutoGen,微软开源的那个多智能体对话框架。在很多项目里,真正让它出圈的不是“能写代码”,而是它把多个AI Agent组织起来,让它们像人开会一样你一言我…

2026/10/19 4:50:02 阅读更多 →
open-code-review:面向生产环境的可审计代码审查CLI

open-code-review:面向生产环境的可审计代码审查CLI

1. 这不是又一个“AI写代码”玩具:open-code-review 的真实定位与不可替代性你可能已经点开过十几个标着“AI Code Review”的开源项目,下载、安装、跑 demo,然后发现——它要么在 PR 描述里胡乱夸你“逻辑清晰”,要么对着一行if …

2026/10/19 4:50:02 阅读更多 →
开源本地化代码审查工具 open-code-review 实战指南

开源本地化代码审查工具 open-code-review 实战指南

1. 这不是又一个“AI写代码”玩具,而是一套能嵌入真实开发流水线的开源代码审查工作流我第一次在团队内部试运行open-code-review的时候,没敢直接推到主分支,而是先拉了个feat/open-cr-test分支,把上周刚合并的三个 PR 全部回滚重…

2026/10/19 4:50:02 阅读更多 →
室内AI出图三周实战路线:从零基础到稳定交付效果图

室内AI出图三周实战路线:从零基础到稳定交付效果图

刚收到一位做室内设计的同行私信,开口就问:“室内AI出图要学多久?我看别人发的那种效果图太惊艳了,但自己连从哪下手都不知道。”我的回答很直接:三周,足够你从完全没碰过AI出图,到稳定输出客户…

2026/10/19 4:49:02 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →