C/C++之动态内存管理方式(new delete)
在C/C编程中动态内存管理是核心能力之一而new与delete正是实现这一功能的关键操作符。它们不仅是内存分配与释放的工具更与对象的生命周期、资源管理深度绑定。一、new与delete的设计初衷超越“内存分配”的对象管理C语言通过malloc()和free()实现动态内存管理但这两个函数仅关注“内存块的分配与释放”与“对象”无关——它们不会处理对象的初始化构造和清理析构。而C作为面向对象语言需要一种能将“内存分配”与“对象构造”绑定、“内存释放”与“对象析构”绑定的机制new与delete由此诞生。简单来说new 分配内存 调用构造函数初始化对象delete 调用析构函数清理对象资源 释放内存。这种“内存操作”与“对象生命周期”的绑定是new/delete与malloc()/free()的核心区别也是C面向对象特性的重要支撑。二、new的工作原理与语法形式new的核心功能是“在堆上创建对象”其操作可分解为两个步骤调用operator new函数分配原始内存大小为对象类型所占字节数在分配的内存上调用对象的构造函数完成初始化。1. 基本语法单个对象的创建123456789101112131415161718192021222324#include iostreamusingnamespacestd;classObject {public:intvalue;Object(intv) : value(v) {// 构造函数cout Object构造value value endl;}~Object() {// 析构函数cout Object析构value value endl;}};intmain() {// 用new创建单个Object对象自动调用构造函数Object* obj newObject(10);// 输出Object构造value 10cout 对象的值 obj-value endl;// 输出10// 用delete销毁对象自动调用析构函数deleteobj;// 输出Object析构value 10obj nullptr;// 避免野指针return0;}这里的new Object(10)实际执行了分配sizeof(Object)字节的内存假设int占4字节则总大小为4字节调用Object::Object(10)将内存初始化为一个“有意义的对象”。2. 数组的创建new[]与元素初始化当需要创建多个同类型对象时需使用new[]数组形式的new其语法为1类型* 指针 new类型[数量]{初始化列表};new[]的工作流程与单个对象类似但会为数组中的每个元素调用构造函数12345678910111213141516171819202122intmain() {// 创建包含3个Object的数组每个元素调用构造函数Object* arr newObject[3]{1, 2, 3};// 输出// Object构造value 1// Object构造value 2// Object构造value 3// 访问数组元素for(inti 0; i 3; i) {cout arr[ i ].value arr[i].value endl;}// 释放数组需用delete[]而非deletedelete[] arr;// 输出// Object析构value 3// Object析构value 2// Object析构value 1arr nullptr;return0;}关键注意new[]分配的数组必须用delete[]释放否则会导致“部分元素析构函数未被调用”——delete[]会记录数组长度逐个调用元素的析构函数而delete仅调用首个元素的析构函数造成内存泄漏尤其当对象包含动态资源时。3. 内存分配失败的处理异常与nothrow默认情况下new分配内存失败时会抛出std::bad_alloc异常需包含new头文件。若希望失败时返回nullptr而非抛出异常可使用nothrow版本12345678910111213141516#include iostream#include new // 包含nothrow定义usingnamespacestd;intmain() {// 尝试分配极大内存可能失败int* p1 newint[1000000000000];// 失败时抛出bad_alloc异常int* p2 new(nothrow)int[1000000000000];// 失败时返回nullptrif(p2 nullptr) {cout 内存分配失败 endl;// 此句可能执行}else{delete[] p2;}return0;}实际开发中需根据场景选择异常处理方式对关键流程异常能更及时地暴露问题对非关键流程nothrow可简化错误判断。三、delete的工作原理与语法形式delete的核心功能是“销毁堆上的对象并释放内存”其操作可分解为调用对象的析构函数清理对象持有的资源如动态内存、文件句柄等调用operator delete函数释放原始内存归还给操作系统或内存池。1. 单个对象的销毁对于new创建的单个对象用delete销毁12Object* obj newObject(5);// 分配构造deleteobj;// 析构释放若对象持有动态资源如内部有new分配的指针析构函数的作用尤为关键12345678910111213141516171819classResourceHolder {private:int* data;// 动态资源public:ResourceHolder(intsize) {data newint[size];// 分配内部资源cout 分配了 size 个int的资源 endl;}~ResourceHolder() {delete[] data;// 析构时释放内部资源cout 释放了内部资源 endl;}};intmain() {ResourceHolder* rh newResourceHolder(10);// 分配构造内部资源被分配deleterh;// 先调用析构释放内部资源再释放rh本身的内存return0;}若此处误用free(rh)C语言函数则~ResourceHolder()不会被调用data指向的内存永远无法释放造成内存泄漏。这正是delete必须与new配对的原因——它确保了析构函数的执行。2. 数组的销毁delete[]的特殊性对于new[]创建的数组delete[]会先确定数组长度new[]会在内存块头部额外存储长度信息按“从后往前”的顺序调用每个元素的析构函数释放整个数组的内存。若用delete替代delete[]编译器可能只调用首个元素的析构函数后续元素的资源如动态内存将泄漏。例如123// 错误示例用delete释放new[]创建的数组ResourceHolder* arr newResourceHolder[2]{10, 20};// 2个对象各分配资源deletearr;// 仅调用第1个元素的析构函数第2个元素的data内存泄漏四、特殊用法placement new定位newplacement new是一种特殊形式的new允许在已分配的内存上构造对象而不重新分配内存。其语法为1new(内存地址) 类型(构造参数);它的核心场景是“内存池”——预先分配一大块内存后续在上面反复创建/销毁对象避免频繁分配释放内存的开销。123456789101112131415161718192021222324252627282930#include iostream#include new // placement new需包含此头文件usingnamespacestd;classTest {public:intx;Test(intval) : x(val) {cout Test构造x x endl;}~Test() {cout Test析构x x endl;}};intmain() {// 预先分配一块足够大的内存大小为Test对象的大小char* buffer newchar[sizeof(Test)];// 仅分配内存不构造对象// 在buffer指向的内存上构造Test对象placement newTest* t new(buffer) Test(100);// 输出Test构造x 100cout 对象的值 t-x endl;// 输出100// 销毁对象placement new没有对应的delete需手动调用析构函数t-~Test();// 输出Test析构x 100// 释放预先分配的内存用delete[]因为buffer是new[]分配的delete[] buffer;return0;}注意placement new不分配内存因此无需也不能用delete释放对象——需显式调用析构函数再释放原始内存块。五、与malloc()/free()的本质区别特性new/deletemalloc()/free()操作对象针对“对象”分配构造析构释放针对“原始内存块”仅分配/释放类型检查自动匹配类型返回对应类型指针返回void*需手动强转失败处理默认抛异常nothrow版本返回nullptr返回nullptr数组支持new[]/delete[]自动处理长度需手动计算总字节数n * sizeof(类型)重载支持可重载operator new/operator delete不可重载关键原则new分配的内存必须用delete释放malloc()分配的内存必须用free()释放不可混用——否则可能导致析构函数不执行或内存管理混乱。六、常见错误与最佳实践1.混用new与delete[]例如用delete释放new[]创建的数组会导致部分元素析构函数未调用造成资源泄漏。解决严格遵循“new配deletenew[]配delete[]”。2.重复释放内存对同一块内存调用多次delete会导致堆损坏Heap Corruption程序可能崩溃或行为异常。解决释放后将指针置为nullptrdelete nullptr是安全的无副作用。3.野指针操作释放内存后未置空指针后续误操作该指针如访问、再次释放会导致未定义行为。解决释放后立即将指针设为nullptr。4.忽略异常处理默认new分配失败会抛异常若未捕获程序会直接终止。解决关键场景中使用try-catch捕获bad_alloc或用nothrow版本显式判断nullptr。5.过度依赖手动管理复杂程序中手动调用new/delete易因逻辑疏漏导致内存泄漏。解决优先使用C11引入的智能指针std::unique_ptr、std::shared_ptr它们通过RAII资源获取即初始化机制自动管理内存生命周期。new与delete是C动态内存管理的基石它们超越了单纯的内存操作深度整合了对象的构造与析构是面向对象编程的核心支撑。理解其工作原理分配构造、析构释放、掌握数组与单个对象的处理差异、规避常见错误是写出健壮C程序的前提。在现代C开发中虽然智能指针已大幅减少了手动使用new/delete的需求但理解这对操作符的本质仍是掌握内存管理的关键——它不仅关乎代码的正确性更体现了对C对象模型和资源管理哲学的理解。

相关新闻

mimalloc 快速上手:4 条命令替换系统 malloc 的完整指南

mimalloc 快速上手:4 条命令替换系统 malloc 的完整指南

mimalloc 快速上手:4 条命令替换系统 malloc 的完整指南 【免费下载链接】mimalloc mimalloc is a compact general purpose allocator with excellent performance. 项目地址: https://gitcode.com/GitHub_Trending/mi/mimalloc mimalloc 是微软出品的通用内…

2026/8/24 9:16:36 阅读更多 →
Tomcat Docker 官方镜像 JDK 与 JRE 变体揭秘:同一 Tomcat 为何体积能省一半?

Tomcat Docker 官方镜像 JDK 与 JRE 变体揭秘:同一 Tomcat 为何体积能省一半?

Tomcat Docker 官方镜像 JDK 与 JRE 变体揭秘:同一 Tomcat 为何体积能省一半? 【免费下载链接】tomcat Docker Official Image packaging for Apache Tomcat 项目地址: https://gitcode.com/gh_mirrors/to/tomcat Tomcat Docker 官方镜像仓库&…

2026/8/24 9:16:36 阅读更多 →
Pyrlang数据类型终极对照表:atom、pid、improper list、bitstring跨语言转换全解析

Pyrlang数据类型终极对照表:atom、pid、improper list、bitstring跨语言转换全解析

Pyrlang数据类型终极对照表:atom、pid、improper list、bitstring跨语言转换全解析 【免费下载链接】Pyrlang Erlang node implemented in Python 3.5 (Asyncio-based) 项目地址: https://gitcode.com/gh_mirrors/py/Pyrlang Pyrlang 是一个用 Python 3&…

2026/8/24 9:16:36 阅读更多 →

最新新闻

不用COLMAP也能重建3D?3dgs-mcmc随机初始化模式让普通照片直达3D高斯模型

不用COLMAP也能重建3D?3dgs-mcmc随机初始化模式让普通照片直达3D高斯模型

不用COLMAP也能重建3D?3dgs-mcmc随机初始化模式让普通照片直达3D高斯模型 【免费下载链接】3dgs-mcmc [NeurIPS 2024 Spotlight] Implementation of the paper "3D Gaussian Splatting as Markov Chain Monte Carlo" 项目地址: https://gitcode.com/gh_…

2026/8/24 10:09:29 阅读更多 →
Transient最令人震撼的特性:如何跨线程“撤销“已执行的IO事务(Backtracking深度解析)

Transient最令人震撼的特性:如何跨线程“撤销“已执行的IO事务(Backtracking深度解析)

Transient最令人震撼的特性:如何跨线程"撤销"已执行的IO事务(Backtracking深度解析) 【免费下载链接】transient A full stack, reactive architecture for general purpose programming. Algebraic and monadically composable pr…

2026/8/24 10:09:29 阅读更多 →
PyWebCopy新手实战:save_webpage保存单页完全教程,图片CSS与JS自动重映射

PyWebCopy新手实战:save_webpage保存单页完全教程,图片CSS与JS自动重映射

PyWebCopy新手实战:save_webpage保存单页完全教程,图片CSS与JS自动重映射 【免费下载链接】pywebcopy Locally saves webpages to your hard disk with images, css, js & links as is. 项目地址: https://gitcode.com/gh_mirrors/py/pywebcopy …

2026/8/24 10:09:29 阅读更多 →
通用智能体评测:从理论到实践的自动化体系构建

通用智能体评测:从理论到实践的自动化体系构建

1. 从“能用”到“好用”:通用智能体评测的现状与挑战最近和几个做AI应用的朋友聊天,大家不约而同地提到了同一个困惑:市面上各种“智能体”或者“AI Agent”框架层出不穷,每个都说自己功能强大、易于集成。但当我们真正想选一个来…

2026/8/24 10:09:29 阅读更多 →
Tricky Store 模块管理指南:3 步搞定 target.txt 配置

Tricky Store 模块管理指南:3 步搞定 target.txt 配置

Tricky Store 模块管理指南:3 步搞定 target.txt 配置 【免费下载链接】Tricky-Addon-Update-Target-List A KSU WebUI to configure Tricky Store target.txt 项目地址: https://gitcode.com/gh_mirrors/tr/Tricky-Addon-Update-Target-List Tricky Store 的…

2026/8/24 10:09:29 阅读更多 →
APOLLO报‘0 databases‘怎么办?iOS取证数据权限错误排查与chmod/chown修复完整清单

APOLLO报‘0 databases‘怎么办?iOS取证数据权限错误排查与chmod/chown修复完整清单

APOLLO报0 databases怎么办?iOS取证数据权限错误排查与chmod/chown修复完整清单 【免费下载链接】APOLLO Apple Pattern of Life Lazy Outputer 项目地址: https://gitcode.com/gh_mirrors/apollo65/APOLLO APOLLO(Apple Pattern of Life Lazy Ou…

2026/8/24 10:08:29 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →