那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C++內存管理operator new和placement new

冬至子 ? 來源:鳴鳴鑼的小屋 ? 作者:Maxwell Luo ? 2023-07-22 09:58 ? 次閱讀

>>> 背景

最近在看一些C++資料的過程中,說到在初始化列表中使用關鍵字new來分配新內存不是異常安全的,應該使用運算符new。這里就引發了我對C++ new的全新認識。

class A {
public:
    A(int a) : px(new int(a)) {}  // 當然這里基礎類是不會異常的
    int* px;
};

>>> 內容

首先我們來回憶一下最常規的new用法。首先創建一個測試類A,并在其構造和析構函數里面打印提示語句。可以發現,在new一個A對象的時候調用了構造函數,在delete一個A對象的時候析構了此對象。而且與C標準庫中的malloc函數相比,new關鍵字不需要知道分配的字節數,而是對類型大小做了自動推斷,顯然更加方便。

class A {
public:
    A(int a) : _a(a) {
        cout < < "object A(" < < _a < < ") is constructed.n";
    }
    ~A() {
        cout < < "object A(" < < _a < < ") is destructed.n";
    }
    int _a;
};


int main() {
    A* obj = new A(1);
    delete obj;


    return 0;
}
object A(1) is constructed.
object A(1) is destructed.

但是方便的代價就是隱藏了很多細節,從而可能導致使用者在沒有充分理解的情況下造成誤用。其實關鍵字new做了非常多的操作。

這里首先給出3個概念,分別是:關鍵字new、操作符new和放置new(或者說,keywords new、operator new、placement new)。它們之間的關系大概如下所示。

圖片

當我們使用關鍵字new去創建一個對象時,會首先根據A類型推斷出需要申請的內存字節數,然后再交給operator new去按字節數申請一塊可用的內存(否則拋出異常),最后調用類的構造函數創造一個對象保存在申請的這段內存中。

圖片

而placement new起到的作用是在分配好的內存上創建對象,和operator new有那么一點互補的意思。placement new的引入是為了避免一些頻繁的內存申請和回收操作,可以專門申請一塊內存做重復的計算,而不是需要一個對象就申請一個內存,從而提高效率。

圖片

下面是一個比較綜合的例子,來表現這些new之間不同。可以看到,我們首先通過operator new來創建一塊能夠容納3個A對象的內存空間,然后通過placement new來在這個申請好的內存空間上創建對象,最后使用operator delete把申請的空間銷毀。

可以看到operator new不會調用構造函數,operator delete也不會調用析構函數。通過placement new配合起始指針的偏移,可以逐個在新內存上創建有意義的數據對象。

int main() {
    A* mempool = (A*)operator new(sizeof(A) * 3);
    cout < < "Memory is allocated!n";
    A* obj1 = new(mempool) A(1);
    A* obj2 = new(mempool + 1) A(2);
    A* obj3 = new(mempool + 2) A(3);
    cout < < obj1- >_a < < endl;
    cout < < obj2- >_a < < endl;
    cout < < obj3- >_a < < endl;
    operator delete(mempool);
    cout < < obj1- >_a < < endl;
    cout < < obj2- >_a < < endl;
    cout < < obj3- >_a < < endl;


    return 0;
}
Memory is allocated!
object A(1) is constructed.
object A(2) is constructed.
object A(3) is constructed.
1
2
3
35134640
0
1448320

>>> 小結

可以看出,C++在內存分配引入了不少的概念,operator new和operator delete都是可以被自定義類重載的,這就給予了程序員很好的自由度。除了使用new和delete來管理內存外,C++還引入了更為復雜的allocator(或分配器)的概念。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 分配器
    +關注

    關注

    0

    文章

    195

    瀏覽量

    25832
  • C++語言
    +關注

    關注

    0

    文章

    147

    瀏覽量

    7027
收藏 人收藏

    評論

    相關推薦

    深入C++內存管理

    說到 C++內存管理,我們可能會想到棧空間的本地變量、堆上通過 new 動態分配的變量以及全局命名空間的變量等,這些變量的分配位置都是由系統來控制
    發表于 11-12 09:29 ?644次閱讀

    New C++基礎與提高

    New C++基礎與提高-王桂林
    發表于 09-22 15:44

    請問C++new和不用new創建類對象區別是什么?

    起初剛學C++時,很不習慣用new,后來看老外的程序,發現幾乎都是使用new,想一想區別也不是太大,但是在大一點的項目設計中,有時候不使用new的確會帶來很多問題。當然這都是跟
    發表于 11-05 07:27

    A New Standard for Multiproces

    A New Stan
    發表于 09-15 10:06 ?1079次閱讀
    A <b class='flag-5'>New</b> Standard for Multiproces

    placement new詳解

    placement new是重載operator new的一個標準、全局的版本,它不能被自定義的版本代替(不像普通的operator
    發表于 03-02 14:24 ?0次下載

    C++語法的外圍基礎

    程序對內存空間的動態分配的頻繁程度要求簡化語言的相關語法的格式。C++語法規定new算符等效于C語言中mal1oc一類的函數功能;free算符等效于
    發表于 03-15 16:55 ?10次下載

    了解一下比較復雜也非常神秘的new

    new”是C++的一個關鍵字,同時也是操作符。關于new的話題非常多,因為它確實比較復雜,也非常神秘。
    的頭像 發表于 04-23 15:27 ?3676次閱讀
    了解一下比較復雜也非常神秘的<b class='flag-5'>new</b>

    新英特爾C/C++編譯器16.0中C/C++語言的特點

    This talk will cover new features in Intel? C/C++ Compiler 16.0 as part of the Intel? Parallel
    的頭像 發表于 10-23 06:57 ?4302次閱讀

    C++內存管理技術的詳細資料說明

    內存管理C++最令人切齒痛恨的問題,也是C++最有爭議的問題,C++高手從中獲得了更好的性能,更大的自由,
    發表于 03-14 08:00 ?4次下載

    C++內存管理詳細介紹

    引言 說到 C++內存管理,我們可能會想到棧空間的本地變量、堆上通過 new 動態分配的變量以及全局命名空間的變量等,這些變量的分配位置都是由系統來控制
    的頭像 發表于 01-11 10:31 ?2787次閱讀

    如何讓new操作符不分配內存,只構造

    placement new 就可以解決這個問題。我們構造對象都是在一個預先準備好了的內存緩沖區中進行,不需要查找內存內存分配的時間是常數;
    的頭像 發表于 01-19 17:01 ?2052次閱讀

    new和malloc函數詳細分析底層邏輯

    new操作符從自由存儲區(free store)上為對象動態分配內存空間,而malloc函數從堆上動態分配內存。自由存儲區是C++基于new
    的頭像 發表于 04-03 09:29 ?758次閱讀

    嵌入式C++內存管理的應用程序

    說到 C++內存管理,我們可能會想到棧空間的本地變量、堆上通過 new 動態分配的變量以及全局命名空間的變量等,這些變量的分配位置都是由系統來控制
    發表于 10-12 10:37 ?416次閱讀
    嵌入式<b class='flag-5'>C++</b><b class='flag-5'>內存</b><b class='flag-5'>管理</b>的應用程序

    new和malloc的區別

    1. 申請的內存所在位置 new操作符從自由存儲區(free store)上為對象動態分配內存空間,而malloc函數從堆上動態分配內存。自由存儲區是
    的頭像 發表于 11-11 11:29 ?614次閱讀
    <b class='flag-5'>new</b>和malloc的區別

    C++內存管理問題

    寫服務端的,內存是一個繞不過的問題,而用C++寫的,這個問題就顯得更嚴重。進程的內存持續上漲,有可能是正常的內存占用,也有可能是內存碎片,而
    的頭像 發表于 11-13 11:13 ?713次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>內存</b><b class='flag-5'>管理</b>問題
    澳门百家乐官网的公式| 百家乐官网合法| 百家乐官网赌场视屏| 百家乐心态研究| 威尼斯人娱乐 老品牌| 盛世娱乐| 青鹏百家乐官网游戏币| 博彩百家乐龙虎| 大发888怎么玩能赢| 开心8百家乐官网游戏| 正品百家乐官网网站| 芝加哥百家乐的玩法技巧和规则| 博发| 七胜百家乐官网赌场娱乐网规则 | 百家乐官网赌博筹码| 百家乐认牌| 真人轮盘游戏| 百家乐长龙有几个| 玩百家乐都是什么人| 百家乐官网蓝盾假网| 伯爵百家乐娱乐城| 捕鱼棋牌游戏| 百家乐官网赌场详解| 百家乐套路| 奈曼旗| 百家乐乐城皇冠| 大发888官方下载 网站| 百家乐官网白菜价| 百家乐官网变牌器| 百家乐赌场| 澳门百家乐官网网址多少| 百家乐博彩平| 百家乐官网单跳打法| 百家乐庄闲| 益阳市| 真人百家乐免费开户送钱| 哪里有百家乐投注网| 新利网上娱乐| 免费百家乐官网计划工具| 宝胜| 百家乐试玩全讯网2|