C++ new關鍵字簡介

一.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 知道如何用就可以了,是編譯器編譯時候做的事情,不需要我們控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章