2009-09-08 61 views
5

我正在嘗試編寫一個內存分析器,並且到目前爲止已經能夠讓我的自定義函數爲malloc,free,new和delete工作。 我試圖使用__FILE____LINE__記錄重載新方法內的發起者,但(如預期的)它只是提供了重載函數的詳細信息。 有沒有辦法獲得關於發起人的重載函數的細節,而不做任何改變正在測試的組件的現有代碼(如#malloc的#define)?覆蓋「新」和記錄有關調用者的數據

我使用的功能是:

void* operator new (size_t size) 
{ 
    if(b_MemProfStarted) 
    { 
     b_MemProfStarted = false; 
     o_MemLogFile << "NEW: " << "| Caller: "<< __FILE__ << ":" 
       << __LINE__ << endl; 
     b_MemProfStarted = true; 
    } 

    void *p=malloc(size); 
    if (p==0) // did malloc succeed? 
    throw std::bad_alloc(); // ANSI/ISO compliant behavior 

    return p; 
} 

的布爾b_MemProfStarted是用來避免的ofstream和map.insert遞歸調用。

回答

3

你可以寫

new(foo, bar) MyClass; 

在這種情況下,下面的函數被調用

void*operator new(std::size_t, Foo, Bar){ 
    ... 
} 

現在,您可以撥打

new(__LINE__, __FILE__) MyClass; 

void*operator new(std::size_t, unsigned line, const char*file){ 
    ... 
} 
使用數據

添加宏

#define new new(__LINE__, __FILE__) 

被監視會趕上大部分調用,而不需要修改源代碼的代碼。

這並不完美,因爲您可以直接調用操作員新的例子。在這種情況下,預處理器會將你的代碼變成垃圾。我知道沒有更好的辦法。

+0

因爲'new'是一個關鍵字,試圖重新定義它與宏是未定義的行爲(編譯器特定的擴展例外)。我更願意爲'normal''new's有條件地定義一個DEBUG_NEW_PLACEMENT宏,並且只留下顯式的'operator new'和特殊位置'new's。但它仍然不是一個漂亮的解決方案。 –

+0

void * operator new(std :: size_t,unsigned line,const char * file)會失敗,因爲「new」只取得size_t。 不能使用「#define new new(__ LINE__,__FILE__)」和運算符覆蓋,因爲它會嘗試替換覆蓋函數定義中的「new」。 (* __ LINE__,__FILE __)/ *遞歸?* /(std :: size_t) – Gayan

+0

@Charles Bailey - 您能詳細說明一下嗎?我不熟悉DEBUG_NEW_PLACEMENT 我嘗試過「#define new(size)My_New(size,__FILE__,__LINE__)」,但是在做一個「新」時似乎沒有被調用 – Gayan