new的實際形式

2021-03-31 08:56:31 字數 1375 閱讀 6075

如果讓我們過載乙個new操作符號,那麼正統的過載方式為:

void * operator new(unsigned int usize)

(1)

也許你已經發現了,有的時候,new的形式遠比這個複雜,比如mfc(在debug版)下的new就是這麼個模樣:

void * operator new(unsigned int usize, const char * szfilename, int nline)

(2)

當然,它這樣的定義,絲毫不會你使用這樣的方式使用new:

int * p = new int[4];

那麼,我使用這樣的形式,它是怎麼呼叫到(2)的呢?

聰明的你或許已經發現了,在你的檔案中發現了這麼一串巨集:

#ifdef _debug

#define new debug_new

#undef this_file

static char this_file = __file__;

#endif

hoho,看到沒?你的new被替換成了debug_new了。(奇怪麼?怎麼連關鍵字都能被define成別的東東呢?別奇怪,你甚至可以#define while for,看看你的程式會怎麼樣?如果這麼幹,然後給別人看看,試試效果:)

繼續跟蹤,看看debug_new的定義:

#define debug_new new(this_file, __line__)

那麼我們還原到我們原始的使用方式裡,它實際是這樣的:

int * p = new(__file__, __line__) int[4];

最後它到operator new函式裡就成了:

int * p = operator new(sizeof(int)*4, __file__, __line__);

奇怪吧,呵呵,它就是這樣的;

也就是說,你可以自己過載寫乙個new,只要保證第乙個引數是關於型別的size,那麼後面的引數可以隨便給的;所以mfc就利用了這一點,將new過載為2的形式,這樣,他們就可以得到每個new呼叫的檔名以及所在原始檔中的行數,然後全部記錄下來,這樣當delete的時候可以檢查所有原來申請的記憶體,只要有沒有被釋放的記憶體指標(也就是造成了記憶體洩露了),就會給出提示,並且告訴你是哪個new(它位於哪個原始檔的哪一行)申請的記憶體沒有被釋放。

注釋:根據

ansi c

規定,__file__

表示當前原始檔的檔名,

__line__

表示**位於當前原始檔的行數。

visual c++

遵循這一規定,並且有擴充,詳見

msdn。

(四) new的三種形式

在c語言中我們分配堆記憶體一般使用malloc和free這對函式,但在 c 提供了一組操作符用於分配記憶體 new和delete,這是一組和sizeof一樣語言內建的操作符。當new與malloc分配的都是系統已有型別,即 int,char 這些系統已有型別時,兩者並無差別,都是申請記憶體,並且申請...

形式引數和實際引數的區別

形參 全稱為 形式引數 是在定義函式名和函式體的時候使用的引數,目的是用來接收呼叫該函式時傳遞的引數。實參 可以是常量 變數 表示式 函式等,無論實參是何種型別的量,在進行函式呼叫時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。實參和形參的區別 空白...

new有六種過載形式

當寫出 p new p 這樣的 的時候,實際上有兩步操作,首先分配記憶體,然後在分配好的記憶體之上初始化類成員.第二步是有建構函式完成的,第一步就是new函式的工作.全域性的new有六種過載形式,void operator new std size t count throw std bad all...