1. 程式人生 > >今日刷題總結20

今日刷題總結20

構造函數 返回值 log 構造 顯式 庫函數 行動 amp 動態內存分配

C++的內存布局

在C++中內存被分為5個部分,分別是堆、棧、自由存儲區、全局/靜態存儲區以及常量存儲區。

自由存儲區與堆的區別

堆是C語言和操作系統裏的術語,它是由操作系統維護的一塊特殊的內存,當C程序調用malloc函數進行動態內存分配時就是從堆上獲取內存的,而調用free函數可以交還分配的內存。自由存儲區是C++基於new和delete操作符的一個抽象概念,凡是通過new來申請的內存區域都可稱為自由存儲區。幾乎所有的C++編譯器默認都使用堆來實現自由存儲區,即缺省的全局庫函數operator new和operator delete也是按照malloc和free的方式來實現的,這時使用new操作符分配的對象,說它在堆或者自由存儲區上都可以。不過operator new和operator delete是可以被重載的(自定義版本必須位於全局作用域或者類作用域中),可以使用其他內存來實現自由存儲,比如靜態存儲區,這時自由存儲區和堆就不是一個概念了。

new和malloc的區別,delete和free的區別

1)是否調用構造/析構函數

使用new表達式時會執行3步操作:

a)new表達式會調用一個名為operator new(或operator new[])的標準庫函數。該函數分配以一塊足夠大的,原始的,未命名的以便存儲特定類型的對象(或對象數組)。

b)編譯器運行相應的構造函數以構造對象,並為其傳入初始值。

c)對象構造完成以後返回一個指向該對象的指針。

使用delete表達式時會執行2步操作:

a)delete表達式會調用對象的析構函數。

b)編譯器調用名為operator delete(或operator delete[])的標準庫函數釋放內存空間。

而malloc/free只是單純地分配和釋放內存空間,不會調用構造/析構函數。

2)返回類型的安全性

new操作符分配內存成功後,返回的是類對象類型的指針,不需要進行類型轉換,所以new操作符是類型安全的。而malloc內存分配成功返回的是void*,需要進行強制類型轉換換成需要的類型指針。

3)內存分配失敗時的返回值

malloc內存分配失敗時會返回NULL,而new不會,它會拋出bad_alloc異常。

4)是否需要指定內存大小

調用new操作符進行動態內存分配時無需指定內存大小,編譯器會根據類型信息自行計算,而malloc需要顯式地指定所需內存的大小。

5)是否可以被重載

operator new和operator delete可以被重載,標準庫定義了operator new和operator delete的8個重載版本,如下所示

//這些版本可能拋出異常

void *operator new(size_t);//分配一個對象

void *operator new[](size_t);//分配一個對象數組

void *operator delete(void *) noexcept;//釋放一個對象

void *operator delete[](void *) noexcept;//釋放一個對象數組

//這些版本承諾不會拋出異常

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

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

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

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

應用程序可以自定義上面函數版本中的任意一個,前提是自定義的版本必須在全局作用域或類作用域,當把它們定義為類成員函數時,它們是隱式靜態的。malloc/free不允許重載。

參考自http://blog.jobbole.com/102002/

http://www.cnblogs.com/QG-whz/p/5060894.html

今日刷題總結20