過載new造成的BoundsChecker誤報

2021-08-22 20:00:13 字數 1017 閱讀 9458

boundschecker是乙個功能很強大的記憶體/資源洩漏檢查工具,尤其是可以嵌入visual studio的環境中隨著偵錯程式一同執行,使用起來尤其方便。當程式退出後,boundschecker則會彈出乙個檢視,其中記錄了**中發生的記憶體洩漏。

不過,如果我們在**中對記憶體分配做了特殊的處理,就有可能導致boundschecker的誤報。考慮如下**:

#include

void*operatornew(size_tsize)

intmain(void)

在這個程式結束後,boundschecker就會報告有40位元組的記憶體洩漏。很顯然,事實上並非如此。

boundschecker的記憶體洩漏檢查原理是掛鉤了所有的記憶體/資源分配函式和銷毀函式,當記憶體/資源分配時,則跳轉到boundschecker自己的函式中,記錄記憶體塊的位址或資源控制代碼;當銷毀記憶體/資源的時候,boundschecker則會刪除對應的分配記錄。這樣一來,在程式退出後,仍然遺留下來的分配記錄就是記憶體/資源的洩漏了。

對於上面的源**,當啟用boundschecker除錯時,operator new的反彙編**如下:

3:void*operatornew(size_tsize)

4:0040103dpopedi

0040103epopesi

0040103fpopebx

00401040movesp,ebp

00401042popebp

00401043ret

如你所見,01172348這個位址就是boundschecker的記憶體統計函式了。也正因為boundschecker只是簡單收集了記憶體塊的大小而並沒有關心程式設計師是如何實現記憶體分配的,所以這裡的誤報就在所難免了。其實在某種意義上來說,即使是使用了自己的記憶體池,如果分配完後不釋放也可以算作記憶體洩漏——因為這個行為造成了記憶體池的浪費。

但是上面這種過載new倒是會造成類似rational purify的工具進行錯誤的記憶體統計,因為所有的記憶體都在記憶體池中一次性分配好了。

話又說回來——我為什麼要故意和boundschecker對著幹呢?

delete釋放new 造成的洩漏

正常 class ctest private int m value int main return 0 對應的彙編 while 1 對於new,vs2008是在申請記憶體的時候多申請了4個位元組大小的記憶體,用來存放陣列個數,返回給上層使用的是實際位址 4。錯誤的delete class ctes...

new與delete的過載

include stdafx.h include using namespace std include include new 和delete的過載 new new delete delete 適用於極個別情況需要定製的時候才用的到。一般很少用 宣告可以不加 引數 void operator ne...

New運算子的過載

在實現之前我們要清楚new,和delete的工作機理,這是個多麼好的學習機會啊!對與new操作符,其實和sizeof一樣,都是c 內建的,然而像strlen就不是了,strlen屬於函式。對於new的功能我們是沒有辦法改變的,當我們new乙個物件時,new為我們做了兩件事情,一 申請一塊足夠的記憶體...