C++之new 和 delete
new 和 delete要成對使用,且要採取相同形式。
使用new時,會發生2件事,1.記憶體被分配出來;2.針對此記憶體會有一個(更多)建構函式被呼叫;
使用delete,發生2件事,1.針對此記憶體的解構函式被呼叫;2.記憶體被釋放;
舉例:
std::string * stringPtr1 = new std::string;
std::string * stringPtr2 = new std::string[100];
delete stringPtr1;
delete [] stringPtr2;
開發人員為了研究學習他們的軟體使用記憶體的行為特徵,然後修改分配和歸還工作,以求獲得其所建置的系統的最佳效率
定製new和delete:主角是operator new和 operator delete,配角是new-handler
瞭解new-handler的行為:
首先介紹客戶指定的錯誤處理函式的使用方法:呼叫set_new_handler
namespace std{
typedef void (*new_handler) ();------new_handler被定義為函式指標
new_handler set_new_handler(new_handler p) throw(); 返回值是一個指標,指向set_new_handler 被呼叫前正在執行的那個new-handler函式
}
如何為每一個class 設計專屬的new-handlers?需要為class提供自己的set_new_handler和operator new即可。
舉例:
class Widget{
public:
static std::new_handlerset_new_handler(std::new_handler p) throw();
static void* operator new(std::size_t size) throw(std::bad_alloc);
private:
static std::new_handlercurrentHandler;
}
std::new_handler Widget::currentHandler = 0; //Static 成員必須在class 定義式之外定義,除非他們是const且是整數型。
std::new_handler Widget::set_new_handler(std::new_handler p) throw()//標準的set_new_handler
{
std::new_handler oldHandler = currentHandler;
currentHandler = p;
return oldHandler;
}
class NewHandlerHolder{
public:
explicit NewHandlerHolder(std::new_handler nh) : handler(nh){}//防止隱式轉換
~NewHandlerHolder(){std::set_new_handler(handler);} //恢復new_handler
private:
std::new_handler handler;
NewHandlerHolder(const NewHandlerHolder&); //拒絕使用複製和賦值構造
NewHandlerHolder& operator=(const NewHandlerHolder&);
}
void * Widget::operator new(std::size_t size) throw(std::bad_alloc)
{
NewHandlerHolder h(std::set_new_hanlder(currentHandler));//儲存全域性的handler
return ::operator new(size);
}
//採用模板方式建立一個複用的baseclass,採用的方式是CRTP
請記住:
set_new_handler 允許客戶指定一個函式,在記憶體分配無法獲得滿足時被呼叫
Nothrow new是一個頗為侷限的工具,因為它只是用記憶體分配;後繼的建構函式呼叫還是可能丟擲異常
瞭解何時在“全域性性的”或“class 專屬的”基礎上合理體寒預設的new和delete。
1. 為了檢測運用錯誤
2. 為了收集動態分配記憶體之使用統計資訊
3. 為了增加分配和歸還的速度
4.為了降低預設記憶體管理器帶來的空間額外開銷
5.為了彌補預設分配器重的非最佳齊位
6.為了將相關物件成簇集中
7.為了獲得非傳統的行為
舉例:對heap 運用錯誤進行除錯的定製new和delete開發
http://blog.sina.com.cn/s/blog_65e729050100m7uw.html
編寫new和delete時需要固守常規
原則:實現一致性operator new必得返回正確的值;記憶體不足時必得呼叫new-handling 函式;
必須有對付零記憶體需求的準備;避免不慎掩蓋正常形式的new
舉例:滿足前三條
void* operator new(std::size_t size)
{
using namespace std;
if(0 == size){
size = 1;
}
while(true){
void* p = ::operator new(size);
if(null != p) return p;
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
if(globalHandler) (*globalHandler)();
else throw std::bad_alloc();
}
}
如果涉及到派生類繼承要如何處理呢?
calss Base{
public:
static void* operator new(std::size_t size) throw(std::bad_alloc);
static void operator delete(void* rawMemory,std::size_t size) throw();
};
void* Base :: operator new(std::size_t size) throw(std::bad_alloc)
{
if(size != sizeof(base))
return ::operator new(size);
}
void Base::operator delete(void* rawMemory,std::size_t size) throw()
{
if(rawMemory == 0)return ;
if(size != sizeof(Base)){
::operator delete(rawMemory);
return ;
//歸還所指的記憶體
return ;
}
//placement new 和placement delete
placement new的定義如下:
void * operator new(std::size_t, void* pMemory) throw();
步驟一:Widget* pw = new Widget;共有兩個函式被呼叫,1是分配內訓的operator new;一個是Widget的預設建構函式
步驟二:
class Widget{
public;
static void* operator new(std::size_t size,std::ostream& logStream)throw (std::bad_alloc);
static void operator delete(void* pMemory,sdd::size_t size)throw();
}
如果記憶體分配成功,但是在建構函式中失敗的話,執行期系統會做記憶體的處理,它會找尋域operator new
類似的operator delete,否則就會找不到對應的釋放參數 而導致記憶體洩露。
不要掩蓋正常的operator, 一定要成對出現。
相關推薦
C++之new 和 delete
new 和 delete要成對使用,且要採取相同形式。 使用new時,會發生2件事,1.記憶體被分配出來;2.針對此記憶體會有一個(更多)建構函式被呼叫; 使用delete,發生2件事,1.針對此記憶體的解構函式被呼叫;2.記憶體被釋放; 舉例: std::string
C++基礎 new和delete
style 析構函數 對比 pan delete 基本數據類型 交叉 del 報錯 1.new delete 的使用 (1)基本數據類型 int *p = new int(10); delete p; int *p = (int *)malloc(sizeof(int))
C++中new和delete之後發生了什麼
眾所周知,如果我們使用new向系統申請了記憶體,我們應該使用指標指向這一塊記憶體,俾能我們使用結束後,通過delete該指標釋放此記憶體資源。 如果理解只達到這種程度,在記憶體管理稍微複雜一點時便一定會束手無策。總有一些事情比其他事情更基本一點,現在我來談談當我們new和delete之後
C++中new和delete的用法
new和delete運算子用於動態分配和撤銷記憶體的運算子 new用法: 1. 開闢單變數地址空間  
C++之new、delete 與malloc、free
在C/C++程式設計中經常會申請記憶體,而對記憶體的申請釋放操作有兩套方法: new、delete 與malloc、free。 1. 區別 (1). new、delete是c++中的操作符,malloc、free是C中的一個函式,它們都可用於申請動態記憶體和釋放記憶體。 (2)
C++中new和delete的背後
NewTest!wmain: 00aa1020 56 push esi 00aa1021 6a04 push 4 00aa1023 e8b4030000 call NewTest!operator new (00aa13d
C++重寫new和delete,比想像中困難
關於C++記憶體管理這話題,永遠都不過時。在我剛出道的時候,就已經在考慮怎麼檢測記憶體洩漏(https://www.cnblogs.com/coding-my-life/p/3985164.html)。想用一份簡單的程式碼,並且不太影響執行效率去實現記憶體洩漏檢測,是不太現實的。當時覺得重寫new和del
c++中new和delete的區別
new 和delete 是運算子,而不是函式。 new new 運算子的格式: new 型別[初值]; new int; ///開闢一個存放整數的儲存空間,返回一個指向該儲存空間的地址
C++回顧——new和delete
一、物件的建立 當建立一個C++物件時,會發生兩件事: 1)為物件分配記憶體; 2)呼叫建構函式來初始化那個記憶體(C++強迫這樣做是因為未初始化的物件是程式出錯的主要原因) C++把建立一個物件所需要的所有動作都結合在一個稱為new的運算子裡(分配記憶
c++的new和delete的方法使用以及不用new定義變數
new和delete運算子用於動態分配和撤銷記憶體的運算子 new用法: 1. 開闢單變數地址空間 1)new int; //開闢一個存放陣列的儲存空間,返回一個指向該儲存空間的地址.int *a = ne
C++:New和Delete的用法
//C++裡 陣列new 和delete問題 //對於陣列new的不同方式 和不同的釋放方法 //---------------------------------------------
C++ 類(new和delete運算子)
文章概述 new和delete運算子 new和delete運算子 a. new/delete 是C++的運算子;類似於malloc/free,程式執行(動態)得開闢記憶體空間(堆); b. new 可以為內建型別的變數開闢空間,陣列變數,類的物件
C++中new和delete
New運算子 1、new表示式: 當我們使用一條new表示式時: string *sp=newstring(“a value”); string *arr=newstring[10]; 實際上執行了三步操作。第一步,new表示式呼叫一個名為operatornew(或者ope
C++分析New和Delete----C語言Malloc和Free
C++中為什麼不用Malloc和Free,而用New和Delete? <1> 如圖: 類的物件在堆上分配的時候用malloc和free: 我們觀察發現雖然在堆上申請空間了,但並沒有呼叫
c++中new和delete的預設賦值測試
為了測試c++中對new操作符的運算規則是否呼叫預設物件的建構函式進行初始化,故寫出如下的測試demo: #include <iostream> using namespace std;
2.16 C++類與new和delete操作符
運行 out 可能 clas cout std 存儲 分配 程序 參考: http://www.weixueyuan.net/view/6347.html 總結: 當我們需要為類對象動態分配存儲空間時,我們應該使用C++語言提供的new與new[]操作符,而不要使用C
c++中的new和delete
程序設計 wan https 解決 運算符 AI 指向 log cnblogs 對於計算機程序設計而言,變量和對象在內存中的分配都是編譯器在編譯程序時安排好的,這帶來了極大的不便,如數組必須大開小用,指針必須指向一個已經存在的變量或對象。對於不能確定需要占用多少內存的情況,
effective c++ 條款16:成對使用new和delete時要采用相同形式
最好 class 你在 pan TE fec IV line PE 記住: 如果你在new表達式中使用[ ],必須在相應的delete表達式中也是用[ ]。如果你在new時不使用[ ],一定不要在delete時使用[ ]。 string* stringPtr1 = n
effective c++條款16:成對使用new和delete時要採取相同形式
下面的程式碼會產生什麼樣的後果? #include <iostream> using namespace std; int main(void) { std::string *StringArray = new std::string[30]; delete StringAr
effective C++筆記--定製new和delete(二)
文章目錄 編寫new和delete時需固守常規 寫了placement new也要寫 placement delete 編寫new和delete時需固守常規 . 在編寫自己的operator new和operator delete時,需要