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.pswp.cn/web/78139.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78139.shtml
英文地址,請注明出處:http://en.pswp.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 頭尾信息(校驗和、時…