2012-11-15 92 views
4

我正在嘗試編寫一個小內存泄漏檢測工具。如何在C++中編寫一個小內存泄漏檢測?

我的想法是跟蹤我的應用程序 中的動態內存分配生命,以確定內存或未刪除的內存的任何無效訪問,這些訪問可能導致我的應用程序在一段時間內使用核心。

我想寫一個簡單的界面來覆蓋newdelete

而在我重寫的new我想打印功能行地址等,然後調用標準new

有沒有人已經試過這個?我不確定我是否可以從我的班級特定的新操作員調用標準新的。

+3

最簡單的解決方案:cd/project/src; fgrep --silent -r -e「new」&&「編寫更好的代碼」' –

+0

與之關係密切,主要是針對Windows的,但奇怪的是,在閱讀Raymond Chen的博客文章之後,您的問題出現在編寫自己的分配器後:http ://blogs.msdn.com/b/oldnewthing/archive/2012/11/15/10368691.aspx – icabod

+1

[立即檢測Windows上堆損壞錯誤的可能的重複。如何?](http://stackoverflow.com/questions/12724057/immediate-detection-of-heap-corruption-errors-on-windows-how) –

回答

0

在這個問題上我提出了一個特設的解決問題的方法:Immediate detection of heap corruption errors on Windows. How?

在一般情況下,你可以用這個代碼替換您的newdelete

DWORD PageSize = 0; 

inline void SetPageSize() 
{ 
    if (!PageSize) 
    { 
     SYSTEM_INFO sysInfo; 
     GetSystemInfo(&sysInfo); 
     PageSize = sysInfo.dwPageSize; 
    } 
} 

void* operator new (size_t nSize) 
{ 
    SetPageSize(); 
    size_t Extra = nSize % PageSize; 
    nSize = nSize + (PageSize - Extra); 
    return Ptr = VirtualAlloc(0, nSize, MEM_COMMIT, PAGE_READWRITE); 
} 

void operator delete (void* pPtr) 
{ 
    MEMORY_BASIC_INFORMATION mbi; 
    VirtualQuery(pPtr, &mbi, sizeof(mbi)); 
    // leave pages in reserved state, but free the physical memory 
    VirtualFree(pPtr, 0, MEM_DECOMMIT); 
    DWORD OldProtect; 
    // protect the address space, so noone can access those pages 
    VirtualProtect(pPtr, mbi.RegionSize, PAGE_NOACCESS, &OldProtect); 
} 

確定的非法訪問記憶。在進一步的討論中,您會發現泄漏檢測和其他內存錯誤檢測的想法。

如果你想打電話全球newdelete,您可以使用::全局命名空間前綴:

return ::new(nSize); 
0

從類特定的operator new調用::operator new是很好的,很常見。您不能從替換版本::operator new中調用全局運算符new,因爲如果將新運算符替換爲新運算符,則舊運算符不存在。

+0

'mallow'存在;) – PiotrNycz

+0

@PiotrNycz - 'mallow'? '當然,'malloc'存在。這並沒有改變這樣一個事實,即如果您將新的全球運營商更換爲新的,則不能再調用舊的運營商。 –

+0

我從電話打字,當然是'malloc'。你可以從新運算符new調用'malloc' ...對於舊運算符new - 我不確定,從來沒有嘗試過,但也許'dlsym(RTLD_NEXT,「name」)'可以用於檢索舊運算符new - 需要用'nm'檢查運算符new的實際名稱(mangled name)...但正如我所說的,從來沒有使用過dlsym()用於C++函數,只用於C函數... – PiotrNycz

0

上述方法聽起來很合理。您可以對其進行增強,並將每個分配中的一些標識數據存儲到某個數據結構中。這樣,您可以在程序終止時跟蹤所有未釋放的內存,而無需檢查所有分配/釋放日誌。

爲了檢測損壞,您可以在開始之前和結束之後使用填充來包裝每個分配,並用一些預定義模式填充它。釋放內存後,您可以驗證模式是否仍然存在。這會給你一個檢測腐敗的好機會。

您可以調用全球new,其範圍前綴爲:::new