久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 學習資源 > 講師博文 > new和(he)malloc的用法和(he)區別

new和(he)malloc的用法和(he)區別 時(shi)間:2025-01-22      來源:華清遠見(jian)

 一.c++中new的三種使用方法包(bao)括:plain new, nothrow new 和 placement new。

      1. plain new 就是我(wo)們(men)最常(chang)使用(yong)的new的方式,在C++中的定義如下(xia):

    1.1 void* operator new(std::size_t) throw(std::bad_alloc);

    1.2  void operator delete( void *) throw();

          plain new在(zai)分配失敗(bai)的情況下,拋出(chu)異常std::bad_alloc而不(bu)是返回(hui)NULL。

 

      2. nothrow new 是不拋出異常(chang)的運算(suan)符new的形式(shi)。nothrow new在失敗時,返回NULL。定義如(ru)下:

       2.1 void * operator new(std::size_t, const std::nothrow_t&) throw();

         2.2 void operator delete(void*) throw();

   

 3. placement new 意即(ji)“放(fang)置”,這種new允許在一(yi)塊已經分配(pei)成功的(de)內(nei)存上重新構造對象或對象數組。placement new不(bu)用擔心內(nei)存分配(pei)失敗(bai),因為它根(gen)本不(bu)分配(pei)內(nei)存,它做的(de)唯一(yi)一(yi)件事情就是調用對象的(de)構造函數。定義(yi)如下:

      3.1 void* operator new(size_t, void*);

     3.2 void operator delete(void*, void*);

palcement new 的(de)主要用(yong)途就是反復使用(yong)已分配(pei)的(de)內存,避免多次(ci)分配(pei)的(de)開銷和風險。

 

二.malloc的用法

       1.概念

                 ‌malloc函(han)數‌在C語(yu)言中用(yong)于動態分配內(nei)存(cun)。其全稱是memory allocation,用(yong)于申請(qing)一(yi)塊連續(xu)的(de)指定大小的(de)內(nei)存(cun)塊區域,并以void*類型(xing)返回(hui)分配的(de)內(nei)存(cun)區域地址。malloc函(han)數的(de)原型(xing)為:

                 void *malloc(unsigned int size);

               該函數(shu)在內存的動態存儲(chu)區中分(fen)(fen)配(pei)一個長(chang)度為size的連續空間(jian)。如果(guo)分(fen)(fen)配(pei)成功(gong),則(ze)返回(hui)指向被分(fen)(fen)配(pei)內存的指針(zhen);如果(guo)分(fen)(fen)配(pei)失(shi)敗,則(ze)返回(hui)空指針(zhen)NULL。malloc函數(shu)返回(hui)的指針(zhen)需要通過(guo)類(lei)型轉(zhuan)換(huan)才能用于具體的數(shu)據對(dui)象。

1. ‌分配(pei)內存‌:使(shi)用(yong)malloc函數(shu)分配(pei)指定大小的內存塊。例如(ru),分配(pei)100個字節的內存:

int *ptr = (int*)malloc(100 * sizeof(int));

三. new和(he)malloc的區別

1. 申請的(de)內存所在位置

  new操作符從自(zi)由存(cun)儲區(qu)(free store)上(shang)為對象動態(tai)分配(pei)內存(cun)空(kong)間,而malloc函數從堆上(shang)動態(tai)分配(pei)內存(cun)。

  自由(you)存(cun)(cun)(cun)儲(chu)區是(shi)C++基于new操(cao)作符的(de)一個抽象概念,凡是(shi)通過new操(cao)作符進行內(nei)(nei)存(cun)(cun)(cun)申請,該內(nei)(nei)存(cun)(cun)(cun)即為自由(you)存(cun)(cun)(cun)儲(chu)區。而堆是(shi)操(cao)作系(xi)統中的(de)術語(yu),是(shi)操(cao)作系(xi)統所維護的(de)一塊特殊內(nei)(nei)存(cun)(cun)(cun),用(yong)于程序(xu)的(de)內(nei)(nei)存(cun)(cun)(cun)動態分(fen)配(pei),C語(yu)言(yan)使用(yong)malloc從堆上分(fen)配(pei)內(nei)(nei)存(cun)(cun)(cun),使用(yong)free釋放已分(fen)配(pei)的(de)對(dui)應(ying)內(nei)(nei)存(cun)(cun)(cun)。

  那么自由存(cun)儲(chu)區(qu)是(shi)否能夠是(shi)堆(問題(ti)等價(jia)于(yu)(yu)new是(shi)否能在堆上動(dong)態分配內存(cun)),這取決于(yu)(yu)operator new 的實現細(xi)節。自由存(cun)儲(chu)區(qu)不(bu)僅可(ke)以是(shi)堆,還可(ke)以是(shi)靜(jing)態存(cun)儲(chu)區(qu),這都(dou)看operator new在哪里為對象分配內存(cun)。

  特(te)別的,new甚至可以不為(wei)對象分配內(nei)存!定位(wei)new的功能可以辦到這一點(dian):

new (place_address) type

  place_address為一(yi)個指針,代(dai)表一(yi)塊(kuai)內存的地(di)址。當使用(yong)(yong)上面這種僅以一(yi)個地(di)址調(diao)用(yong)(yong)new操作(zuo)符時(shi),new操作(zuo)符調(diao)用(yong)(yong)特殊的operator new,也就是下面這個版本:

void * operator new (size_t,void *) //不(bu)允許重(zhong)定(ding)義這個(ge)版(ban)本的operator new

  這個operator new不分配(pei)任(ren)何的(de)內存(cun),它只是簡單地(di)返(fan)回指針實參,然后右new表(biao)達式負責在place_address指定的(de)地(di)址進(jin)行對象的(de)初(chu)始化(hua)工作。

2.返回類型安全(quan)性

  new操作(zuo)(zuo)符內(nei)存(cun)(cun)分配(pei)成功(gong)時,返回的(de)是(shi)對象類型(xing)的(de)指針,類型(xing)嚴格(ge)與對象匹配(pei),無須進行類型(xing)轉(zhuan)(zhuan)換,故new是(shi)符合類型(xing)安全性的(de)操作(zuo)(zuo)符。而malloc內(nei)存(cun)(cun)分配(pei)成功(gong)則是(shi)返回void * ,需(xu)要通過強(qiang)制類型(xing)轉(zhuan)(zhuan)換將void*指針轉(zhuan)(zhuan)換成我們需(xu)要的(de)類型(xing)。

3.內存分配(pei)失敗時(shi)的返回值

  new內存分配(pei)失敗時,會拋出bad_alloc異常,它不會返(fan)(fan)回(hui)NULL;malloc分配(pei)內存失敗時返(fan)(fan)回(hui)NULL。

  在使用C語言(yan)時,我(wo)們習慣在malloc分配(pei)內存后(hou)判斷(duan)分配(pei)是(shi)否成功:示例如下:

int *a = (int *)malloc ( sizeof (int ));

if(NULL == a){

}

else

{

  ...

}

 c++中(zhong)正確(que)的做法應該是使(shi)用異(yi)常機制:

try

{

  int *a = new int();

}catch (bad_alloc &obj)

{  

    ...

}

 

4.是否需(xu)要指(zhi)定內存大(da)小

  使用new操作符申(shen)請內存分配時無須指(zhi)定內存塊的大(da)小,編(bian)譯器會(hui)根據類(lei)型信息(xi)自行計算,而malloc則需(xu)(xu)要(yao)顯式地指(zhi)出所需(xu)(xu)內存的尺(chi)寸。

class Demo{...

 

};

 

int main()

{

    Demo * ptr = new Demo ;

Demo * ptr = (Demo *)malloc(sizeof(Demo )); //需要顯式指定所需內(nei)存大小sizeof(Demo );

}

 

  當(dang)然了,我這里使用malloc來為(wei)我們(men)自定義類型分配內存是不(bu)怎(zen)么合適的,請看下(xia)一條。

 

5.是(shi)否調用構造函數/析構函數

  使用new操作符來分配對象(xiang)內存時會經歷三個步驟:

  第一(yi)步(bu):調用operator new 函數(對(dui)于數組是operator new[])分配一(yi)塊足(zu)夠大的(de),原始(shi)的(de),未命名的(de)內存空(kong)間以便存儲特定類型的(de)對(dui)象。

  第二步:編(bian)譯器運(yun)行相(xiang)應的構造(zao)函數(shu)以構造(zao)對(dui)象,并為其傳入初值。

   第三部(bu):對(dui)象構造完成后(hou),返回一個指向該對(dui)象的(de)指針。

  使(shi)用delete操作(zuo)符來釋放對(dui)象(xiang)內存(cun)時會經歷兩個步(bu)驟(zou):

  第(di)一步:調用對(dui)象的析構函數。

  第二步(bu):編(bian)譯器調用(yong)operator delete(或operator delete[])函數(shu)釋放內存空間。

  總之來說(shuo),new/delete會(hui)調用對象(xiang)的(de)構(gou)造函數/析構(gou)函數以完(wan)成對象(xiang)的(de)構(gou)造/析構(gou)。而malloc則不會(hui)。示(shi)例如(ru)下:

class Demo

{

 

public:

    Demo() :a(1), b(1.2)

    {

        cout << __LINE__ << &quot;:" << __func__ << endl;

    }

 

private:  

 

   int a;

    double b;

};

 

int main()

 

{

 

  Demo * ptr = (Demo*)malloc(sizeof(Demo)); //構造函數(shu)沒有調用

 

   return 0;

 

}

 

 

而使(shi)用new來(lai)分配(pei)對象時,示例如下:

class Demo

{                      &nbsp;                               

public:

    Demo() :a(1), b(1.2)

    {   

        cout << a << ":" << b << endl;

    }   

 

private:

    int a;

    double b;

};

 

int main()

{

    Demo * ptr = new Demo;

    return 0;

}

6.對數組的(de)處(chu)理

  C++提供(gong)了new[]與delete[]來專門(men)處理數組類型:

   ;   A * ptr = new A[10];//分配10個A對象

 

  使用new[]分配的內存必須使用delete[]進行(xing)釋放(fang):

      delete [] ptr;

 

  new對(dui)數(shu)(shu)(shu)組(zu)的支持體現在它會分別調用構造函數(shu)(shu)(shu)函數(shu)(shu)(shu)初始化每一(yi)個數(shu)(shu)(shu)組(zu)元素(su),釋放對(dui)象(xiang)(xiang)時為每個對(dui)象(xiang)(xiang)調用析構函數(shu)(shu)(shu)。注(zhu)意(yi)delete[]要(yao)與new[]配套(tao)使用,不然會找出(chu)數(shu)(shu)(shu)組(zu)對(dui)象(xiang)(xiang)部(bu)分釋放的現象(xiang)(xiang),造成(cheng)內存泄漏。

  至于(yu)malloc,它并知道你在這塊(kuai)內(nei)存(cun)上要放(fang)的數組(zu)還是(shi)啥別的東西,反正(zheng)它就(jiu)給你一塊(kuai)原始的內(nei)存(cun),在給你個內(nei)存(cun)的地址就(jiu)完事。所以(yi)如(ru)果要動態分配一個數組(zu)的內(nei)存(cun),還需要我(wo)們手動指定數組(zu)的大小:

    int * ptr = (int *) malloc( sizeof(int)* 10 );//分(fen)配一個(ge)10個(ge)int元素的(de)數組(zu)

 

7.new與malloc是否可以(yi)相互調用

  operator new /operator delete的(de)實(shi)現可以(yi)基于malloc,而malloc的(de)實(shi)現不可以(yi)去調用new。下面是編(bian)寫operator new /operator delete 的(de)一種簡單方式,其(qi)他版本也與(yu)之類似:

1. void * operator new (sieze_t size)

2. {

3.     if(void * mem = malloc(size)

4.      &nbsp;  return mem;

5.     else

6.    &nbsp;    throw bad_alloc();

7. }

8. void operator delete(void *mem) noexcept

9. {

10.       free(mem);

11. }

 

8.是否(fou)可以被重載

  opeartor new /operator delete可以被重(zhong)載。標準庫(ku)是(shi)定義(yi)了operator new函數(shu)和operator delete函數(shu)的8個重(zhong)載版本(ben):

//這些(xie)版本可能拋出(chu)異常

1. void * operator new(size_t);

2. void * operator new[](size_t);

3. void * operator delete (void * )noexcept;

4. void * operator delete[](void *0)noexcept;

//這些(xie)版本承諾不拋出異常

5. void * operator new(size_t ,nothrow_t&) noexcept;

 6. void * operator new[](size_t, nothrow_t& );

7. void * operator delete (void *,nothrow_t& )noexcept;

8. void * operator delete[](void *0,nothrow_t&; )noexcept;

  我們(men)可(ke)以自(zi)定義上面函數版本(ben)中的任意一個,前提是自(zi)定義版本(ben)必須位于全局(ju)作(zuo)用域或者類(lei)作(zuo)用域中。太細節(jie)的東西不在這里(li)講述,總之,我們(men)知(zhi)道我們(men)有(you)足(zu)夠的自(zi)由去重載operator new /operator delete ,以決定我們(men)的new與delete如(ru)何為對象分(fen)配內存,如(ru)何回收(shou)對象。

  而malloc/free并不允(yun)許重載。

9. 能(neng)夠直觀(guan)地重(zhong)新分配(pei)內存

  使(shi)(shi)用malloc分配(pei)的內(nei)存(cun)(cun)(cun)后,如(ru)果在使(shi)(shi)用過程中(zhong)發現(xian)內(nei)存(cun)(cun)(cun)不足,可以使(shi)(shi)用realloc函數進(jin)行內(nei)存(cun)(cun)(cun)重新(xin)分配(pei)實現(xian)內(nei)存(cun)(cun)(cun)的擴(kuo)充。realloc先判斷當前的指針所指內(nei)存(cun)(cun)(cun)是(shi)否有(you)(you)足夠的連續空(kong)間(jian),如(ru)果有(you)(you),原(yuan)地(di)擴(kuo)大可分配(pei)的內(nei)存(cun)(cun)(cun)地(di)址,并且返回原(yuan)來的地(di)址指針;如(ru)果空(kong)間(jian)不夠,先按照新(xin)指定的大小分配(pei)空(kong)間(jian),將(jiang)原(yuan)有(you)(you)數據從頭到(dao)尾(wei)拷貝到(dao)新(xin)分配(pei)的內(nei)存(cun)(cun)(cun)區域,而(er)后釋放原(yuan)來的內(nei)存(cun)(cun)(cun)區域。

  new沒有這樣直(zhi)觀的配套設施來(lai)擴充內存。

10. 客戶(hu)處理(li)內(nei)存分配不足(zu)

  在operator new拋出異常以反映一個(ge)未獲得(de)滿足的需求之前(qian),它會先(xian)調用一個(ge)用戶(hu)指定(ding)的錯誤處理(li)函數,這就是new-handler。new_handler是一個(ge)指針類型:

1. namespace std

2. {

3. typedef void (*new_handler)();

4. }

  指向了一(yi)個(ge)沒有參(can)數(shu)沒有返回值(zhi)的函數(shu),即(ji)為錯誤處理函數(shu)。為了指定錯誤處理函數(shu),客戶需要調(diao)用(yong)set_new_handler,這(zhe)是一(yi)個(ge)聲明的一(yi)個(ge)標準庫函數(shu):

1. namespace std

2. {

3.     new_handler set_new_handler(new_handler p ) throw();

4. }

  set_new_handler的(de)參數(shu)為new_handler指針,指向了(le)operator new 無法分配(pei)足夠內存時該(gai)調用(yong)的(de)函數(shu)。其(qi)返回值也(ye)是個指針,指向set_new_handler被調用(yong)前正在執(zhi)行(xing)(但馬上就要發(fa)生替換)的(de)那個new_handler函數(shu)。

  對(dui)于malloc,客戶并不(bu)(bu)能夠去編程決定內(nei)存不(bu)(bu)足(zu)以分配時(shi)要干(gan)什么事,只能看著malloc返回NULL。

總結

  將上面所(suo)述(shu)的10點差別整(zheng)理成表格:

上一篇:如何解決深度學習中的梯度消失和梯度爆炸問題

下一篇:基于RISC-V的輕量級操作系統設計

戳我(wo)查看嵌入式每月就(jiu)業風云榜

點我了解(jie)華清遠見高校學霸學習秘籍

猜(cai)你(ni)關心(xin)企(qi)業(ye)是如何評價華清學員的

干貨分(fen)享
相(xiang)關新聞
前臺(tai)專線:010-82525158 企業(ye)培訓洽談專(zhuan)線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2024 北京華清遠見科技發展有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部