C 刪除空指標的乙個坑

2021-07-25 03:11:04 字數 1925 閱讀 9480

最近使用了專案公共庫中看起來很穩定的乙個訊息佇列類(前同事留下的),起初用得還挺好。後來程式中突然出現了記憶體暴漲的情況,最後定位下來是這個類的問題。隨後花了一些時間定位出現問題的**,其實在debug時都沒有找到問題**,真正找到問題是憑著感覺在一堆**裡揪出了這樣一句話:

delete (void*)lparam;

靈感突現,這句應該有問題。當時在辦公室,不能上網且手裡又沒有現成的參考資料,於是隨手寫了個簡單的demo測試這句話。

class ca

; ~ca()

;private:

char *m_tmp;

};int _tmain(int argc, _tchar* argv)

return

0;}

果然記憶體蹭蹭蹭就漲上去了。看了的確不能這樣用。那麼問題又來了,delete p1;與delete ca 又有何區別呢?

懷著一顆好奇心,我用vs編譯後下斷點,直接檢視反彙編。

delete ca;//

0028106f test esi,esi

00281071 je wmain+85h (281085h)

00281073

mov eax,dword ptr [esi]

00281075

push eax

00281076

call edi

00281078

push offset string "\xcf\xfa\xbb\xd9ca" (2820fch)

0028107d call ebx

0028107f push esi

00281080

call edi

00281082

add esp,0ch

delete p1;

00281085

push esi

00281086

call edi

00281088

add esp,4

delete (ca*)p1;

0028108b test esi,esi

0028108d je wmain+0a1h (2810a1h)

0028108f mov ecx,dword ptr [esi]

00281091

push ecx

00281092

call edi

00281094

push offset string "\xcf\xfa\xbb\xd9ca" (2820fch)

00281099

call ebx

0028109b push esi

0028109c call edi

0028109e add esp,0ch

彙編用得很少,不過基本的東西看懂應該沒問題。由於是使用win32release版本,所以沒有那麼多干擾項,edi的值就是delete操作的位址,esi的值是ca指標的位址。能夠直接看到delete p1時,只將ca位址入棧,然後call delete操作。而delete ca時,彙編有一大堆,主要功能是將ca類的析構函式展開成彙編。當然這是msvc編譯器做的事情。我就沒有繼續深究下去了。

回到家,順便查了下資料。原來對乙個void*型別的delete,是不會呼叫類本身的析構方法的。這個結論與我得出的相符,只不過我使用反彙編的推論侷限於編譯器。

乙個關於空指標的思考

最近在看 時發現乙個用於求結構體成員偏移量的方式 define nbb offsetof struct,field nbb buf size nbb byte struct 0 field nbb byte 0 奇怪的是對 struct 0 field的引用怎麼不會出現錯誤呢?於是寫了如下 進行簡單...

今天解決了乙個空指標

swagger裡傳入請求資料時,老是報nullpointerexception debug時發現會出現這麼一行 cannot find local variable 原因是資料庫表裡後來加了個擴充套件欄位param1,然而在請求報文裡有命名規範為sid,雖然實體類裡改了資料庫的字段,但是請求報文轉換...

乙個指標釋放後不置空的危害

今天面試碰到這個問題了,可以說這個問題是我回答最冤枉的。我覺得我對這個問題,有很清晰的認識。但是不知道為什麼,嘴禿嘍了一句記憶體洩漏,真想打自己乙個大嘴巴。記憶體洩漏的情況的產生是 例如 用int p int malloc sizeof int 讓p重新指向其它,這樣用malloc 開闢的空間就找不...