new和malloc的区别

1 语义层级不同:语言机制 vs. 库函数

new / new[] (C++ 关键字)malloc / calloc / realloc (C 运行时函数)
本质语言级运算符;可被重载库函数;无法重载
作用分配内存 并调用构造函数仅分配原始字节块,不做初始化,也不调用构造函数
返回类型指向 请求类型 的指针;无需强制类型转换void*;C++ 中需显式转换
失败处理默认抛出 std::bad_allocnothrow 版本返回 nullptr返回 nullptr,并设置 errno
释放方式delete / delete[]:先调用析构函数,再归还内存free():直接释放字节块

2 对象生命周期:构造 / 析构自动 VS 手动

// new:安全地构造对象
std::string* ps = new std::string("hi");   // 调用了 std::string 的构造函数
delete ps;                                 // 调用析构函数,再归还内存// malloc:只得到裸内存,需要手动“放置构造”(placement new)
void* raw = std::malloc(sizeof(std::string));
std::string* ps2 = new (raw) std::string("hi"); // 构造
ps2->~std::string();                            // 手动析构
std::free(raw);

若忘记任何一步就会造成 未定义行为内存泄漏


3 类型与对齐保障

  • new 按目标类型所需的 最严对齐 分配;
    自 C++17 起,malloc 也保证返回能满足 max-align(通常 ≥16 byte) 的地址,但老代码仍可能在自定义对齐要求(例如 SIMD 类型)下依赖 new

  • new[] 还需在实现内部保存元素个数,以便 delete[] 正确调用每个元素的析构函数——这部分管理开销是 malloc 不具备的。


4 可定制性

  • 重载 operator new / operator delete
    全局类内 均可,用于内存池、调试填充、对齐扩展等。
    例:

    void* MyClass::operator new(std::size_t sz) { return MyPool::allocate(sz); }
    void  MyClass::operator delete(void* p)     { MyPool::deallocate(p); }
    
  • malloc 不能按对象粒度定制,只能整体替换底层分配器(如 jemalloc、tcmalloc)或在使用层面改写为 mymalloc()


5 异常安全与 RAII

new 的异常语义与 C++ 的 RAII 配合天然一致:对象构造失败时抛异常,上层 catch 后无泄漏。
使用 malloc 时必须手动检查返回值并在出错路径中 free() 已成功分配的资源。


6 何时选用哪一个?

场景建议
绝大多数 C++ 代码,直接需要对象使用 new/delete ——保证构造/析构正确发生
需要与 C 库接口共享内存(libc, POSIX API, MPI 等)或操作纯字节缓冲区使用 malloc/free
自己管理对象池、序列化缓冲,不希望逐对象开销malloc+placement new 或者 重载 operator new
性能敏感的大批量小对象重载 operator new 或专业分配器(tcmalloc, jemalloc, std::pmr

切勿交叉释放

  • mallocdelete

  • newfree
    违者均是未定义行为。


7 常见误解澄清

  1. 效率new 不必然更慢——主开销往往在底层分配算法,而不是是否调用构造函数;自定义 operator new 可以比裸 malloc 更快。

  2. 初始化为 0:只有 new int()new int[10]() 才会零初始化;new int 保留未定义值,与 malloc 返回值同样“脏”。

  3. 内存来源:在大多数实现里 new 仍然最终调用某种 malloc,但附带额外的语言级步骤;标准层面它们依旧完全不同的抽象。


一句话总结

new = 分配内存 + 构造对象 + 类型安全 + 异常语义;
malloc = 只要一块原始字节,剩下的你自己负责。

掌握两者差异,才能在系统编程与高性能场景中游刃有余。

是的,你理解得基本正确,我来系统梳理一下这件事:


new 会自动调用构造函数(创建)和析构函数(销毁)

MyClass* p = new MyClass(123); // 自动调用构造函数 MyClass(123)
...
delete p;                      // 自动调用析构函数 ~MyClass()

这个过程:

  • 分配内存(内部可能调用 malloc 或其他分配器)

  • 调用构造函数,初始化对象

  • delete 会反过来先调用析构函数,再释放内存

所以用 new 分配的对象,不需要你手动构造和析构,只要 new / delete 配对即可。


malloc 只分配“原始内存”,不会自动构造或析构

void* mem = malloc(sizeof(MyClass)); // 没有调用构造函数
MyClass* p = static_cast<MyClass*>(mem);

这时,p 指向一块“未初始化的内存”,你不能直接使用它:

❗你必须这样手动构造:

new (p) MyClass(123); // placement new:在已有内存上构造对象

❗用完后手动析构 + 释放内存:

p->~MyClass();        // 显式调用析构函数
free(p);              // 再释放原始内存

📌 总结一下区别:

操作new / deletemalloc / free
内存分配自动完成手动 malloc(sizeof(T))
构造函数调用自动(带参数或默认)❌ 不会;需手动 placement new
析构函数调用自动❌ 不会;需手动 对象->~类名()
安全性 / 易错性高,配合 RAII 可防泄漏容易出错,忘构造或析构都会导致 UB 或泄漏

✅ 示例对比(完整代码)

使用 new(推荐方式)
MyClass* p = new MyClass(10);
// ... 使用 p
delete p;
使用 malloc(必须小心)
void* mem = malloc(sizeof(MyClass));
MyClass* p = new (mem) MyClass(10); // placement new
// ... 使用 p
p->~MyClass(); // 手动析构
free(mem);     // 手动释放内存

🔥 总结:用 malloc 管理对象时,你每次都必须手动调用构造和析构函数

但用 new 时,这些操作都自动完成,更安全、更方便,推荐优先使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78139.shtml

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

相关文章

C++11新特性_自动类型推导_auto

在 C11 标准中&#xff0c;auto关键字被赋予了全新且强大的功能&#xff0c;它用于自动类型推导&#xff0c;即编译器能够根据变量的初始化表达式自动确定其类型。 基本语法 使用auto声明变量时&#xff0c;只需给出auto关键字&#xff0c;后面紧跟变量名&#xff0c;并对其进…

[预备知识]6. 优化理论(二)

优化理论 本章节介绍深度学习中的高级优化技术&#xff0c;包括学习率衰减、梯度裁剪和批量归一化。这些技术能够显著提升模型的训练效果和稳定性。 学习率衰减&#xff08;Learning Rate Decay&#xff09; 数学原理与可视化 学习率衰减策略的数学表达&#xff1a; 步进式…

【计算机视觉】语义分割:Mask2Former:统一分割框架的技术突破与实战指南

深度解析Mask2Former&#xff1a;统一分割框架的技术突破与实战指南 技术架构与创新设计核心设计理念关键技术组件 环境配置与安装指南硬件要求安装步骤预训练模型下载 实战全流程解析1. 数据准备2. 配置文件定制3. 训练流程4. 推理与可视化 核心技术深度解析1. 掩膜注意力机制…

数字智慧方案5857丨智慧机场解决方案与应用(53页PPT)(文末有下载方式)

资料解读&#xff1a;智慧机场解决方案与应用 详细资料请看本解读文章的最后内容。 随着科技的飞速发展&#xff0c;智慧机场的建设已成为现代机场发展的重要方向。智慧机场不仅提升了旅客的出行体验&#xff0c;还极大地提高了机场的运营效率。本文将详细解读沃土数字平台在…

【C到Java的深度跃迁:从指针到对象,从过程到生态】第五模块·生态征服篇 —— 第二十章 项目实战:从C系统到Java架构的蜕变

一、跨语言重构&#xff1a;用Java重写Redis核心模块 1.1 Redis的C语言基因解析 Redis 6.0源码核心结构&#xff1a; // redis.h typedef struct redisObject { unsigned type:4; // 数据类型&#xff08;String/List等&#xff09; unsigned encoding:4; // …

ES6异步编程中Promise与Proxy对象

Promise 对象 Promise对象用于解决Javascript中的地狱回调问题&#xff0c;有效的减少了程序回调的嵌套调用。 创建 如果要创建一个Promise对象&#xff0c;最简单的方法就是直接new一个。但是&#xff0c;如果深入学习&#xff0c;会发现使用Promise下的静态方法Promise.re…

UE自动索敌插件Target System Component

https://www.fab.com/zh-cn/listings/9088334d-3bde-4e10-a937-baeb780f880f ​ 一个完全用 C 编写的 UE插件&#xff0c;添加了对简单相机锁定/瞄准系统的支持。它最初​​在蓝图中开发和测试&#xff0c;然后转换并重写为 C 模块和插件。 特征&#xff1a; 可通过一组可在…

中小企业MES系统概要设计

版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、系统架构设计 1.1 整体架构模式 采用分层微服务架构&#xff0c;实现模块解耦与灵活扩展&#xff0c;支持混合云部署&#xff1a; #mermaid-svg-drxS3XaKEg8H8rAJ {font-family:"trebuchet ms",verdana,ari…

STM32移植U8G2

STM32 移植 U8G2 u8g2 &#xff08;Universal 8bit Graphics Library version2 的缩写&#xff09;是用于嵌入式设备的单色图形库&#xff0c;可以在单色屏幕中绘制 GUI。u8g2 内部附带了例如 SSD13xx&#xff0c;ST7xx 等很多 OLED&#xff0c;LCD 驱动。内置多种不同大小和风…

Langchain,为何要名为langchian?

来听听 DeepSeek 怎么说 Human 2025-05-02T01:13:43.627Z langchain 是一个大语言模型开发框架。我的理解中&#xff0c;lang 是词根"语言"&#xff0c;chain是单词"链"&#xff0c;langchain 便是将语言模型和组件串联成链的框架。而 langchain 的图标是…

Windows下Python3脚本传到Linux下./example.py执行失败

1. 背景 大多数情况下通过pycharm编写Python代码&#xff0c;编写调试完&#xff0c;到Linux下发布执行。 以example.py脚本为例 #! /usr/bin/env python3 #! -*- encoding: utf-8 -*- def test(x,y): xint x yint y cxy return c if _name_"__main__": print(test(2…

当MCP撞进云宇宙:多芯片封装如何重构云计算的“芯“未来?

当MCP撞进云宇宙:多芯片封装如何重构云计算的"芯"未来? 2024年3月,AMD发布了震撼业界的MI300A/B芯片——这颗为AI计算而生的"超级芯片",首次在单封装内集成了13个计算芯片(包括3D V-Cache缓存、CDNA3 GPU和Zen4 CPU),用多芯片封装(Multi-Chip Pac…

用定时器做微妙延时注意事项

注意定时器来着APB1还是APB2&#xff0c;二者频率不一样&#xff0c;配置PSC要注意 &#xff08;1&#xff09;高级定时器timer1&#xff0c; timer8以及通用定时器timer9&#xff0c; timer10&#xff0c; timer11的时钟来源是APB2总线 &#xff08;2&#xff09;通用定时器ti…

三类思维坐标空间与时空序位信息处理架构

三类思维坐标空间与时空序位信息处理架构 一、静态信息元子与元组的数据结构设计 三维思维坐标空间定义 形象思维轴&#xff08;x&#xff09;&#xff1a;存储多媒体数据元子&#xff08;图像/音频/视频片段&#xff09; 元子结构&#xff1a;{ID, 数据块, 特征向量, 语义…

spring boot中@Validated

在 Spring Boot 中&#xff0c;Validated 是用于触发参数校验的注解&#xff0c;通常与 ​​JSR-303/JSR-380​​&#xff08;Bean Validation&#xff09;提供的校验注解一起使用。以下是常见的校验注解及其用法&#xff1a; ​1. 基本校验注解​​ 这些注解可以直接用于字段…

Hadoop 单机模式(Standalone Mode)部署与 WordCount 测试

通过本次实验&#xff0c;成功搭建了 Hadoop 单机环境并运行了基础 MapReduce 程序&#xff0c;为后续分布式计算学习奠定了基础。 掌握 Hadoop 单机模式的安装与配置方法。 熟悉 Hadoop 环境变量的配置及 Java 依赖管理。 使用 Hadoop 自带的 WordCount 示例程序进行简单的 …

历史数据分析——运输服务

运输服务板块简介: 运输服务板块主要是为货物与人员流动提供核心服务的企业的集合,涵盖铁路、公路、航空、海运、物流等细分领域。该板块具有强周期属性,与经济复苏、政策调控、供需关系密切关联,尤其是海运领域。有不少国内股市的铁路、公路等相关的上市公司同时属于红利…

openEuler 22.03 安装 Mysql 5.7,TAR离线安装

目录 一、检查系统是否安装其他版本Mariadb数据库二、环境检查2.1 必要环境检查2.2 在线安装&#xff08;有网络&#xff09;2.3 离线安装&#xff08;无网络&#xff09; 三、下载Mysql2.1 在线下载2.2 离线下载 四、安装Mysql五、配置Mysql六、开放防火墙端口七、数据备份八、…

喷泉码技术在现代物联网中的应用 设计

喷泉码技术在现代物联网中的应用 摘 要 喷泉码作为一种无速率编码技术,凭借其动态生成编码包的特性,在物联网通信中展现出独特的优势。其核心思想在于接收端只需接收到足够数量的任意编码包即可恢复原始数据,这种特性使其特别适用于动态信道和多用户场景。喷泉码的实现主要…

GZIPInputStream 类详解

GZIPInputStream 类详解 GZIPInputStream 是 Java 中用于解压缩 GZIP 格式数据的流类,属于 java.util.zip 包。它是 InflaterInputStream 的子类,专门处理 GZIP 压缩格式(.gz 文件)。 1. 核心功能 解压 GZIP 格式数据(RFC 1952 标准)自动处理 GZIP 头尾信息(校验和、时…