過載全域性new,delete
對與new操作符,其實和sizeof一樣,都是c++內建的,然而像strlen就不是了,strlen屬於函式。對於new的功能我們是沒有辦法改變 的,當我們new乙個物件時,new為我們做了兩件事情,一、申請一塊足夠的記憶體空間供存放物件,對於new乙個陣列物件,編譯器會計算出總共的空間,然 後執行類似c語言中malloc函式類似的功能。二、初始化物件,對於單個物件,包括包括基本物件和類物件,可以通過括號初始化,比如int * pn = new int(3); a * pa = new a(3); 然而對於陣列不能初始化,對於類物件,必須定義無引數的建構函式。對與new的基本功能我們是無法改變的。
我們所能改變的就是如何為物件分配記憶體,我們可一過載這個函式以實現分配記憶體。通常的過載方式是:
void * operator new (size_t size);
然而這已經足夠了,在一般的operator new 過載函式裡,我們可以再加入其它引數,但第乙個引數必須是size_t型別,即為無符號整形。正是有這種特性,為我們對記憶體申請和釋放的跟蹤提供了可能。
具體實現就是第乙個operator new 的過載函式,我們第一的這個函式是這樣的:
void * operator new(unsigned int size, const char *file, int line)
然後用巨集替換所有的new:
#define new new(__file__, __line__)
這樣我們每次呼叫new,比如int * pn = new int;被編譯器替換成了int * pn = new (__file__, __line__) int,從而呼叫我們定義的operator new,這種辦法確實很妙。需要交代的是,對於陣列同樣適用,而是在編譯的是後由編譯器計算出所需要的長度呼叫我們定義的operator new函式。
對於delete,我們無需使用巨集定義,只要過載operator delete就可以了,然而我們需要過載兩個delete:
void operator delete(void * p)
void operator delete (void * p)
其實後面乙個函式的內容和前面的內容一樣,但為了支援陣列的釋放,我們必須是要定義的。那麼我們只是簡單的free(p)編譯器咋知道我們釋放的陣列,還 是單個物件了,這個不用我們操心了,我們只要提供給free函式乙個申請記憶體的首位址就可以了。因為在用malloc申請的時候,我們也把數組裝換為記憶體 大小了。
由此我們可以得出下面的推斷:用int * pn = new int [100];的空間,用delete pn釋放和delete pn釋放效果一樣。然而那麼既然這兩種方式一樣,那還要delete 幹什麼,其實delete 有另外的作用就是類物件陣列的釋放,編譯器把delete 解釋為呼叫物件的析構函式,這個是通過迴圈實現的,最後釋放掉申請的記憶體。
既然我們已經跟蹤了new和delete,那麼就可以比較容易的判斷申請的記憶體是否最後得到釋放,要完成它,我們還需要乙個鍊錶,或者其它,當我們申請一 塊記憶體的時候加入到鍊錶中,釋放一塊空間的時候,從鍊錶中刪除和釋放記憶體首位址相同的節點就可以了,最後理想的情況是鍊錶為空,如果不為空,那就說明記憶體 發生洩露(memory leaks)了。
完整**:
#include "malloc.h"
#include "iostream.h"
#ifdef _debug
void * operator new(unsigned int size, const char *file, int line)
void operator delete(void * p)
void operator delete (void * p)
void operator delete(void * p, const char *file, int line)
void operator delete (void * p, const char *file, int line)
#define new new(__file__, __line__)
#endif
void main()
c 中的過載全域性new,delete
這樣我們每次呼叫new,比如int pn new int 被編譯器替換成了int pn new file line int,從而呼叫我們定義的operator new,這種辦法確實很妙。需要交代的是,對於陣列同樣適用,而是在編譯的是後由編譯器計算出所需要的長度呼叫我們定義的operator new函...
過載全域性new delete實現記憶體檢測
下面介紹用過載new delete運算子的方式來實現乙個簡單的記憶體洩露檢測工具,基本思想是過載全域性new delete運算子,被檢測 呼叫new和delete運算子時就會呼叫過載過的operator new和operator delete,在過載的operator new裡和operator d...
C 筆記,過載new , delete 操作符
1.簡述 1 自定義過載全域性的new 和 delete,在使用new新增物件和delete物件時,會呼叫自定義全域性的new和delete操作,c 內部類也 如char,int等 不例外,同樣會呼叫自定義的new和delete。2 也可以定義作用域為當前類的new和delete,即像在類中過載其他...