一.new的基本用法
1.c++通過new關鍵字進行動態分配內存。
2.new開闢的空間存儲在堆上,而我們定義的變量存儲在棧上。
3.new分配的空間使用delete釋放,new[] 使用 delete[]。
4.
int* pi = new int(5);//表示動態分配一個int ,初始化爲 5
int* pa = new int[5];//表示動態分配一個數組,數組大小爲5
二.new和malloc的區別
1.malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用於申請動態內存和釋放內存。
2.對於非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。 由於malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加於malloc/free。
3.new操作符內存分配成功時,返回的是對象類型的指針,類型嚴格與對象匹配,無須進行類型轉換;malloc內存分配成功則是返回void * ,需要通過強制類型轉換將void*指針轉換成我們需要的類型。
4.new內存分配失敗時,會拋出bac_alloc異常,它不會返回NULL;malloc分配內存失敗時返回NULL。
5.使用new操作符申請內存分配時無須指定內存塊的大小,編譯器會根據類型信息自行計算;malloc則需要顯式地指出所需內存的尺寸。
三.應用
//這看起來似乎是一個單一運算,它其實是由兩個步驟完成。
//這裏的new 相當於 new operator
int *pi = new int(5);
1.通過適當的new運算符函數實例,配置所需的內存:
int *pi = __new(sizeof(int));
2.將配置得來的對象設立初值:
*pi = 5;
更進一步地說,初始化操作應該在內存配置成功(經由new運算符)後才執行。
3.delete運算符情況類似。
delete pi;
如果pi的值爲0,c++語言會要求delete運算符不要有操作。因此編譯器必須爲此調用構造一層保護膜:
if(pi != 0)
{
__delete(pi);
}
注意:pi並不會因此被自動清除爲0;
4.new operator
就是我們平常用的new
new operator實際上執行了以下幾個步驟:
①調用operator new分配內存。
如果類本身未定義operator new,那麼會調用全局的operator new。
// 全局 operator new
void * operator new(std::size_t size) throw(std::bad_alloc)
{
if (size == 0)
{
size = 1;
}
void* p;
while ((p = ::malloc(size)) == 0)
{ //採用 malloc 分配空間
std::new_handler nh = std::get_new_handler();
if (nh)
nh();
else
throw std::bad_alloc();
}
return p;
}
每個類可以重載operator new(),如果類自己定義了operator new(),則調用自己的定義的 operator new,而不是全局的。
通過定義可以發現operator new()只是分配了內存空間。
②通過placement new來調用構造函數
void* operator new (std::size_t size, void* ptr) noexcept;
placement new不需要拋出異常,因爲它自身不分配內存。
ptr指針是已經分配好的,可能在棧上也可能在堆上。
placement new僅在一個已經分配好的內存指針上調用構造函數,placement new 知道如何用就可以了,是編譯器編譯時候做的事情,不需要我們控制。