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運算符定義一個多維數組變量或數組對象時,它產生一個指向數組第一個元素的指針,返回的類型保持了除最左邊維數外的所有維數。