1. 程式人生 > 實用技巧 >C++ new 運算子 用法總結

C++ new 運算子 用法總結

C++ new 運算子 用法總結

使用 new 運算子 分配記憶體 並 初始化

1.分配記憶體初始化標量型別(如 int 或 double),在型別名後加初始值,並用小括號括起,C++11中也支援大括號。

int * pi = new int (6); 
double * pd = new double (9.99); 
//C++11中, 支援以下寫法
int * pi = new int {6}; 
double * pd = new double {9.99};

2.初始化結構或陣列,需要使用大括號列表初始化 ,需編譯器 支援 C++11

struct where{double x; double y; double z;};
where * one = new where {1.2, 2.2, 3.2};
int * ar = new int [4] {1, 2, 3, 4};

3.使用 delete 釋放 new分配的記憶體 (僅限於常規 new 分配的 堆記憶體)

delete pi;
delete pd;
delete one;
// 釋放陣列 記住 加[]
delete [] ar;

4.建立類物件

(1)new建立物件,pTest用來接收物件指標。new申請的物件,則只有呼叫到delete時才會執行解構函式,如果程式退出而沒有執行delete則會造成記憶體洩漏:

CTest*  pTest = new  CTest();  delete pTest;

(2)不用new,直接使用類定義申明,使用完後不需要手動釋放,該類解構函式會自動執行:

CTest  mTest;

(3)使用普通方式建立的類物件,在建立之初就已經分配了記憶體空間。而類指標,如果未經過物件初始化,則不需要delete釋放:

CTest*  pTest = NULL;

new 失敗時處理方式

1.常規分配記憶體,呼叫建構函式。分配失敗時,丟擲異常。定義如下:

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

void operator delete(void *) throw();

分配失敗則丟擲異常std::bad_alloc,不是返回NULL,所以判斷返回值是否為NULL是沒用的

char *p=new char[size]; //分配失敗,不是返回NULL

delete [] p;

2.不丟擲異常。分配失敗時,返回NULL。定義如下:

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

void operator delete(void*) throw();

char *p=new(nothrow) char[size]; //分配失敗,是返回NULL
if(NULL==p)

cout<<"alloc failure!"<<endl;

new: 運算子、函式和替換函式

運算子new 和 new [] 分別呼叫如下函式:

void * operator new(std::size_t);		//use by new
void * operator new [] (std::size_t);		//use by new []

運算子delete 和 delete [] 分別呼叫如下函式:

void * operator delete(void *);		//use by delete
void * operator delete [](void *);		//use by delete []

這些函式稱為 分配函式 ,位於全域性名稱空間中。std::size_t 是一個 typedef。

例:

int * pi = new int;
//將轉換為下面這樣
int * pi = new (sizeof(int));

int * pi = new int[40];
//將轉換為下面這樣
int * pi = new (40 * sizeof(int));

//同樣的
delete pi;
//將轉換為下面這樣
delete (pi);

定位 placement new 運算子

通常,new負責在 堆 中分配一個足以滿足要求的記憶體塊,但 定位new可以讓程式設計師指定要使用的記憶體位置。不會記憶體分配失敗,因為它根本不分配記憶體,只調用物件的建構函式。它允許在一塊已經分配成功的記憶體上重新構造物件或物件陣列。定義如下:

void* operator new(size_t,void*);

void operator delete(void,void);

1.使用 定位new運算子,首先要包含 標頭檔案 new

#include<new>
using namespace std;
struct chaff
{
    char dross[20];
    int slag;
};
char buffer1[50];
char buffer2[200];
int main()
{
    chaff * p1, p2;
    p2 = new (buffer1) chaff;	// 在buffer1中
    p2 = new (buffer2) int[20]; // 在buffer2中
}

2.使用placement new構造起來的物件或陣列,要顯式呼叫它們的解構函式來銷燬(解構函式並不釋放物件的記憶體),千萬不要使用delete.這是因為placement new構造起來的物件或陣列大小並不一定等於原來分配的記憶體大小,使用delete會造成記憶體洩漏或者之後釋放記憶體時出現執行時錯誤。

3.當使用new運算子定義一個多維陣列變數或陣列物件時,它產生一個指向陣列第一個元素的指標,返回的型別保持了除最左邊維數外的所有維數。