C++ --内存管理
C内存分区布局程序运行时内存被划分为几个逻辑区域内存区域存储内容生命周期特点栈函数局部变量、函数参数、返回值自动管理进入函数分配退出释放大小固定通常几MB访问最快溢出风险堆动态分配的对象new/delete手动管理直到显式释放大小受系统限制访问较慢可能产生碎片全局/静态区全局变量、static变量程序启动分配程序结束释放分为已初始化和未初始化常量区字符串常量、const修饰的全局数据程序启动分配程序结束释放通常只读试图修改会导致段错误代码区编译后的机器指令程序启动加载只读防止意外修改C内存管理方式通过new和delete操作符进行动态内存管理。一、管理内置类型int、数组等1. 单个内置类型变量#include iostream int main() { // 分配一个int初始化为10 int* p new int(10); std::cout *p std::endl; // 输出 10 // 使用完毕后释放 delete p; p nullptr; //置空防止野指针 return 0; }2. 内置类型数组#include iostream int main() { // 分配包含5个int的数组未初始化 int* arr new int[5]; // 赋值 for (int i 0; i 5; i) { arr[i] i * 10; } // 打印 for (int i 0; i 5; i) { std::cout arr[i] ; // 输出 0 10 20 30 40 } std::cout std::endl; // 释放数组内存注意是 delete[] delete[] arr; arr nullptr; return 0; }new[]必须配delete[]否则未定义行为可能内存泄漏或崩溃。二、管理自定义类型类对象1. 单个对象#include iostream #include string class Student { private: std::string name; int age; public: // 构造函数 Student(const std::string n, int a) : name(n), age(a) { std::cout 构造函数: name 被创建 std::endl; } // 析构函数 ~Student() { std::cout 析构函数: name 被销毁 std::endl; } void display() const { std::cout 姓名: name , 年龄: age std::endl; } }; int main() { // 在堆上创建Student对象 Student* s new Student(张三, 20); s-display(); // 输出: 姓名: 张三, 年龄: 20 // 释放对象先调用析构函数再释放内存 delete s; s nullptr; return 0; }输出顺序构造函数: 张三 被创建姓名: 张三, 年龄: 20析构函数: 张三 被销毁关键机制new做了两件事1.分配内存 2.调用构造函数delete也做两件事1. 调用析构函数 2.释放内存2. 自定义类型数组#include iostream #include string class Student { // ... 同上 ... }; int main() { // 分配包含3个Student对象的数组 // 注意这样会调用默认构造函数所以类必须有无参构造 Student* students new Student[3]{ {李四, 22}, // 可以用初始化列表 {王五, 23}, {赵六, 24} }; // 遍历访问 for (int i 0; i 3; i) { students[i].display(); } // 释放数组注意是 delete[] delete[] students; students nullptr; return 0; }new[]分配对象数组时要求类有默认构造函数如果类没有默认构造函数可以用new[] 初始化列表new/delete的底层机制一、new表达式的完整执行流程当你下new Student(张三, 20)时编译器会将其展开为三个步骤// 伪代码展示 new 的内部实现 Student* s new Student(张三, 20); // 等价于以下三步 // 步骤1调用 operator new 分配原始内存 void* raw_mem operator new(sizeof(Student)); // 步骤2在该内存上构造对象调用构造函数 Student* s new(raw_mem) Student(张三, 20); // placement new // 步骤3返回指针 return s;详细拆解步骤操作说明1. 内存分配operator new(sizeof(T))底层通常调用malloc()也可能重载2. 对象构造在原始内存上调用构造函数使用placement new3. 返回指针返回构造好的对象地址类型已转换为T*二、delete表达式的完整执行流程// 伪代码展示 delete 的内部实现 delete s; // 等价于以下两步 // 步骤1调用析构函数 s-~Student(); // 步骤2调用 operator delete 释放内存 operator delete(s);详细拆解步骤操作说明1. 对象析构调用析构函数~Student()释放对象内部持有的资源如动态成员2. 内存释放operator delete(ptr)底层通常调用free()也可能重载operator new与operator delete函数new和delete是用户进行动态内存申请和释放的操作符operator new和operator delete是 系统提供的全局函数new在底层调用operator new全局函数来申请空间delete在底层通operator delete全局函数来释放空间。数组版本new[]和delete[]数组版本特殊之处在于需要记录数组元素个数以便正确调用每个元素的析构函数。// new[] 的内部机制简化 int* arr new int[10]; // delete[] 会先读取元素个数然后依次调用析构函数最后释放内存 delete[] arr;实际分配的内存布局[元素个数 n][元素0] [元素1] ... [元素9]返回的是指向第一个元素的指针所以new[]必须配delete[]如果错用delete它不会读取元素个数只调用第一个元素的析构然后错误地释放整块内存。new/delete与malloc/free的对比对比维度new/deletemalloc/free本质C 运算符关键字C 标准库函数内存分配调用operator new→malloc直接调用malloc构造函数自动调用不调用析构函数自动调用不调用返回值类型类型安全T*void*需强制转换内存大小编译器自动计算手动指定sizeof失败处理抛出std::bad_alloc异常返回NULL是否可重载可以重载operator new不可重载分配数组new T[n]自动处理需手动计算总大小定位new表达式(placement-new)定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。使用格式new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针initializer-list是类型的初始化列表。使用场景内存池预先申请大块内存然后用 placement new 逐个构造对象。因为内存池分配出的内存没有初始化所以如果是自定义类型的对象需要使用new的定义表达进行显示调构造函数进行初始化。#include iostream #include new // 必须包含 class Widget { int data; public: Widget(int d) : data(d) { std::cout 构造 Widget, data data std::endl; } ~Widget() { std::cout 析构 Widget std::endl; } }; int main() { // 1. 先分配原始内存 void* raw_mem operator new(sizeof(Widget)); // 2. 在原始内存上构造对象placement new Widget* w new (raw_mem) Widget(42); // 3. 使用对象 // ... // 4. 显式调用析构注意不能 delete因为内存不是 new 分配的 w-~Widget(); // 5. 释放原始内存 operator delete(raw_mem); return 0; }关键代码void* raw_mem operator new(sizeof(Widget));这行做了什么调用operator new分配原始内存不构造任何对象返回void*指针指向一块sizeof(Widget)大小的未初始化内存这块内存是原始的里面是随机字节类似malloc的行为内存状态raw_mem 指向的 4/8/... 字节 [XX XX XX XX ...] 垃圾数据未初始化Widget* w new (raw_mem) Widget(42);这是placement new语法它做了以下事情不分配任何内存使用raw_mem指向的已有内存在raw_mem位置调用Widget的构造函数返回构造好的对象指针类型为Widget*内存状态变为raw_mem/w 指向的内存 [42] [其他成员变量...] 已初始化有效对象

相关新闻

Android NDK开发核心技巧与高频问题解决方案

Android NDK开发核心技巧与高频问题解决方案

1. Android NDK开发概述与核心痛点在移动应用开发领域,Android NDK(Native Development Kit)一直是处理高性能计算、复用现有C/C代码库的关键工具。作为一位经历过数十个NDK项目的开发者,我深刻体会到:NDK开发就像在Ja…

2026/7/21 20:17:22 阅读更多 →
AI 续写歌曲工具怎么选:8 款 AI 作曲与旋律生成工具的适用环节

AI 续写歌曲工具怎么选:8 款 AI 作曲与旋律生成工具的适用环节

没有乐理基础时,作曲为什么让人却步很多人不是没有旋律感,而是不知道怎样把脑海里的几句哼唱继续写下去。想到和弦、调式、编曲这些词,作曲就像一道需要先学几年乐理才能跨过的门槛。其实对新手来说,第一步不必是完成一首制作精细…

2026/7/21 16:02:01 阅读更多 →
Python条件分支:if else语句详解与应用实践

Python条件分支:if else语句详解与应用实践

1. 程序流程控制的基础:if else的本质在编程世界里,if else语句就像交通信号灯一样控制着程序的执行路径。当我们需要根据不同的条件执行不同的代码块时,if else结构就是最基础也是最强大的工具之一。它让程序具备了"思考"能力&…

2026/7/22 21:00:48 阅读更多 →

最新新闻

ClineRule系统提示词

ClineRule系统提示词

零容错设计原则(Fail Fast)任何异常/失败/边界情况必须立即暴露,宁可崩溃不可静默。 参考:docs/KnowLedge/零容错设计原则.md(完整版)哲学基础 软件熵增定律错误被掩盖 系统熵增,错误被暴露 系…

2026/7/23 22:09:11 阅读更多 →
虚拟机双网卡配置+uboot nfs下载zImage

虚拟机双网卡配置+uboot nfs下载zImage

校园网下虚拟机双网卡配置uboot nfs下载zImage 一、问题描述 环境:校园网网络 基于网线使用nfs进行远程下载需要使用桥接模式 需要使用NAT模式确保网络 NFS下载文件报错:Loading: *** ERROR: File lookup fail 二、虚拟机配置双网卡 打开虚拟机的…

2026/7/23 22:09:11 阅读更多 →
机器学习:数据的标注

机器学习:数据的标注

1.4数据的标注 1.监督学习(有输入和输出): 在已知输入和输出的情况下,通过训练建立起输入到输出的映射模型,应用最广的机器学习方法,可进一步分为分类和回归两类算法 2.无监督学习(没有输出&…

2026/7/23 22:09:11 阅读更多 →
Three.js 渲染管线揭秘:从几何体到像素的 GPU 绘制流程

Three.js 渲染管线揭秘:从几何体到像素的 GPU 绘制流程

Three.js 渲染管线揭秘:从几何体到像素的 GPU 绘制流程 一、3D 大屏的帧率,怎么就突然崩了 3D 可视化大屏上线第一周,物体数量刚过一万,帧率从 60 掉到 12。老板站在屏幕前数秒数,研发比他还尴尬。这事我见过太多团队栽…

2026/7/23 22:09:11 阅读更多 →
基于SpringBoot的大学生旅游平台的设计

基于SpringBoot的大学生旅游平台的设计

摘 要 在信息技术迅猛发展的大环境之下,大学生旅游市场上的消费行为表现出非常鲜明的多元化特点。传统的获取信息的途径已经不能适应现代用户对于高效率、社交属性旅行服务的要求。为了克服以上问题,本文使用Spring Boot框架来创建一个专门给大学生使用…

2026/7/23 22:09:11 阅读更多 →
ChatGPT、Codex、Plus与Pro:AI写代码越快,任务越要先拆清楚

ChatGPT、Codex、Plus与Pro:AI写代码越快,任务越要先拆清楚

过去使用AI写代码,很多开发者最关注的是提示词。需求怎么描述,技术栈怎么指定,输出格式怎么限制,怎样让模型一次生成更多代码,几乎成了AI编程的核心技巧。但当ChatGPT开始参与需求分析,Codex开始进入代码仓…

2026/7/23 22:08:11 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻