c++中new和delete的使用方法
摘自:http://www.cnblogs.com/jjzhou1988/archive/2008/11/30/1344314.html
new和delete運算子用於動態分配和撤銷記憶體的運算子
new用法:
1. 開闢單變數地址空間
1)new int; //開闢一個存放陣列的儲存空間,返回一個指向該儲存空間的地址.int *a = new int 即為將一個int型別的地址賦值給整型指標a.
2)int *a = new int(5) 作用同上,但是同時將整數賦值為5
2. 開闢陣列空間
一維: int *a = new int[100];開闢一個大小為100的整型陣列空間
二維: int **a = new int[5][6]
三維及其以上:依此類推.
一般用法: new 型別 [初值]
delete用法:
1. int *a = new int;
delete a; //釋放單個int的空間
2.int *a = new int[5];
delete [] a; //釋放int陣列空間
要訪問new所開闢的結構體空間,無法直接通過變數名進行,只能通過賦值的指標進行訪問.
用new和delete可以動態開闢,撤銷地址空間.在程式設計序時,若用完一個變數(一般是暫時儲存的陣列),下次需要再用,但卻又想省去重新初始化的功夫,可以在每次開始使用時開闢一個空間,在用完後撤銷它.
/* C++中的 new / delete */
/*****************************************************************************/
/*
new的3種形態: new operator , operator new , placement new
new operator:
new操作符,像 + - * / && . :: ?: 等操作符一樣,是語言內建的, 它
不能被過載,不能改變其行為。
它的行為包括分配記憶體的 operator new 和呼叫建構函式的 placement new。
new operator 實際上做了三件事:獲得一塊記憶體空間、呼叫建構函式、返回
正確的指標。如果建立的是簡單型別(如char)的變數,那麼第二步會被省略。
比如:
CTest* pT = new CTest(1, 2);
它的呼叫實際上等效於:
void* p = operator new( sizeof(CTest) );
CTest* pT = new(p) CTest(2, 2);
其中前一句是operator new分配記憶體,後一句是placement new呼叫構造函
數,並返回正確的CTest*指標。
operator new:
操作符new,原型為:
void* operator new(size_t size);
它分配指定大小的記憶體, 可以被過載, 可以新增額外的引數, 但第一個引數
必須為 size_t 。
它除了被 new operator 呼叫外也可以直接被呼叫, 如:
void* p = operator new(sizeof(CTest));
這種用法和呼叫 malloc 一樣, 只分配了sizeof(CTest)大小的記憶體。
placement new:
置換new,原型為:
void operator new(size_t size,void*p);
它在一塊指定的記憶體上呼叫建構函式, 包含標頭檔案<new>之後也可
以直接使用,如:
CTest* pT = new(p) CTest(2, 2);
他在p這塊記憶體上呼叫CTest的建構函式來初始化CTest。
如果用 placement new 構造出來的物件,必須顯示的呼叫物件的解構函式,
如:
pT->~CTest();
然後釋放能存, 呼叫 operator delete (對應於分配時的 operator new)
operator delete(pT);
delete operator:
delete操作符,和 new operator 一樣,不能被過載,不能改變其行為。
delete operator 做的事有:呼叫解構函式,然後呼叫operator delete來
釋放記憶體,比如:
delete pT;
它的呼叫實際上等效於:
pT->~CTest();
operator delete(pT);
operator delete:
操作符delete,原型為:
void*operator delete(void *p)
同理,對應於分配記憶體的 operator new,釋放記憶體的為 operator delete ,
它也可以被過載。
operator new []
operator delete []
也是同樣原理 ....
******************************************************************************/
/*****************************************************************************/
/* new 的基本使用指南 */
/*****************************************************************************/
/*
1)、想在堆上建立一個物件,應該用 new 操作符,它既分配記憶體又為物件呼叫構
造函式。
2)、如果僅僅想分配記憶體,就應該呼叫 operator new 函式;它不會呼叫建構函式。
3)、如果想定製在堆物件被建立時的記憶體分配過程,應該過載 operator new 函式,
然後使用 new operator,new operator 會呼叫定製的 operator new 。
4)、如果想在一塊已經獲得指標的記憶體裡建立一個物件,應該用 placement new 。
placement new 主要適用於:
(a): 對時間要求非常高的應用程式中,因為這些程式分配的時間是確定的;
(b): 長時間執行而不被打斷的程式;
(c): 以及執行一個垃圾收集器 (garbage collector) 。
注意:如果用 placement new 構造出來的物件,必須顯示的呼叫物件的解構函式。
******************************************************************************/
/*****************************************************************************/
/* delete this */
/*****************************************************************************/
/*
如上所述,呼叫 delete pT; 的執行可以看作如下這樣一個過程:
pT->~CTest();
operator delete(pT);
其中:
pT->~CTest() 語句呼叫解構函式。(解構函式本身是不會釋放記憶體的)
operator delete(pT) 釋放記憶體。 (這是一個物件在消亡之前的最後動作)
若CTest類過載了operator delete(), 那麼將不呼叫全域性的operator delete(pT),
而是呼叫 pT->operator delete(pT)(在CTest::operator delete()內最好還應該呼叫
全域性的operator delete來釋放記憶體)。
問:成員函式呼叫 delete this 合法嗎?
答:只要你小心,一個物件請求自殺(delete this),是可以的!
以下是對 "小心" 的定義:
1)、必須100%的確定:物件是用 new 分配的(不是用new[],也不是用
placement new,也不是一個棧上的區域性物件,也不是全域性的,也不
是另一個物件的成員,而是明白的普通的 new )。
2)、必須100%的確定:該成員函式是物件最後呼叫的的成員函式。
3)、必須100%的確定:該成員函式在 delete this 之後的程式碼中不接觸到
物件的任何一塊(包括呼叫任何其他成員函式或訪問任何資料成員)。
4)、必須100%的確定:在 delete this 之後不再去訪問this指標。你不能
去檢查它,將它和其他指標比較,和NULL比較,列印它,轉換它...,
不能對它做任何事。
自然,對於這種情況還要習慣性地告誡:當你的指標是一個指向基類類
型的指標,而沒有虛解構函式時(也不可以delete this)。因為是在類
成員函式裡面delete this的,所以在此語句以後,不能訪問任何成員變
量及虛擬函式(呼叫虛擬函式必須物件例項存在以檢查型別),否則一定非法。
上面所說的情況,在執行時不一定會報錯,但儘量不要這麼做。因為,一般來
說,記憶體釋放釋放的只能是資料段的內容(包括堆和棧,但釋放棧上的記憶體由系統
進行),而程式碼段的記憶體在記憶體中是永遠不會釋放/改變的,直到程式結束。因此
在記憶體釋放後也是可以訪問的。所以,一般所謂的釋放記憶體delete操作,是在資料
段進行的釋放。但是,並不要因為這樣,就違背上面的原則。
******************************************************************************/
/*-----------* 下面是 new 應用例項 *----------------------------------------------*/
/*
F1 中的 new operator,他的行為就像F2中的 operator new 和 placement new 一樣,
也可以用F3中的方法達到相同的效果。
*/
#include <new>
#include <stdio.h>
class CTest
{
public:
CTest(int _x, int _y)
{
X = _x;
Y = _y;
}
~CTest()
{
X = 0;
Y = 0;
}
void Test(char* sz)
{
printf("%s: X=%d Y=%d /n", sz, X, Y);
}
int X;
int Y;
};
/*
new operator:
*/
void F1()
{
CTest* pT = new CTest(1, 1); // new operator
pT->Test("F1");
delete pT;
}
/*
operator new
placement new
*/
void F2()
{
void* p = operator new(sizeof(CTest)); // operator new : 分配記憶體
CTest* pT = new(p) CTest(2, 2); // placement new: 構造物件
pT->Test("F2");
pT->~CTest(); // 必須顯示析構物件
operator delete(pT); // operator delete: 釋放記憶體
}
/*
也可這樣實現:
*/
void F3()
{
char* p = new char[sizeof(CTest)]; // new operator: char為內建型別,不會呼叫建構函式,相當於只分配記憶體
CTest* pT = new(p) CTest(3, 3); // placement new: 在這塊記憶體上構造CTest物件
pT->Test("F3");
pT->~CTest(); // 必須顯示析構CTest物件
delete [] p; // delete operator: char為內建型別,不會呼叫解構函式,相當於只釋放記憶體
}
void main()
{
F1();
F2();
F3();
}
相關文章
- C++記憶體管理:new / delete 和 cookieC++記憶體deleteCookie
- C malloc() free(), C++ new() delete()C++delete
- C++動態記憶體管理——new/deleteC++記憶體delete
- 程式設計中new[]和delete[]應該如何使用?程式設計delete
- <七>深入理解new和delete的原理delete
- C/C++中的new/delete、構造/解構函式、dynamic_cast分析C++delete函式AST
- 記憶體(new delete )記憶體delete
- JavaScript中的new map()和new set()使用詳細(new map()和new set()的區別)JavaScript
- new、delete、記憶體分配 的底層原理delete記憶體
- 【C++】C++ new和malloc到底哪裡不一樣C++
- 從預設解構函式學習c++,new,delete,記憶體洩漏,野指標函式C++delete記憶體指標
- laravel中delete()方法和destroy()方法的區別Laraveldelete
- 淺析c++11中的“=default“和“=delete“C++delete
- C++中的&和&&C++
- postgresql和mysql中的limit使用方法MySqlMIT
- Python中類的建立和使用方法Python
- SQL中DATEADD和DATEDIFF的使用方法SQL
- C++中list的使用方法及常用list操作總結C++
- Sqlserver、oracle中Merge的使用方法,一個merge語句搞定多個Insert,Update,Delete操作SQLServerOracledelete
- C++ new用法的個人見解C++
- PHP new self()和new static()的區別PHP
- python中__init__ 和__new__的對比Python
- Java 中的 clone( ) 和 new,哪個效率更高?Java
- Unfolder中的補丁和元素使用方法
- 深入理解 Go 中的 new() 和 make() 函式Go函式
- C#/Vsto中CustomTaskPanes和Ribbon的使用方法C#
- C++用new建立二維陣列的方法C++陣列
- C++中的NULL和nullptrC++Null
- C++ 中的 volatile 和 atomicC++
- C++中&和*的含義C++
- C和C++中的staticC++
- 理解new和實現一個new
- PHP 的 new static 和 new self 具體有什麼?PHP
- delete和truncate刪除的區別delete
- C++ 使用 new 建立二維陣列C++陣列
- C++ opencv中的namedWindow和imshowC++OpenCV
- Python中__new__和__init__的區別與聯絡Python
- Golang make和new的區別Golang
- SQLSERVER 的 truncate 和 delete 有區別嗎?SQLServerdelete