return导致内存泄露。C函数中不要有多次return,以及其解决方法。goto的用法。
函數中隨處return,是造成我們資源泄露和程序死鎖的主要根源。很多同志寫過類似的代碼,函數中創建了和引用了多個資源,中間使用的過程中出錯了,程序return,經典的代碼是這樣的:
void?fun() ? {Lock(mutex);mem?=?malloc(size);if?(null?==?mem){ ?????????return;?//死鎖 ????} ????fh?=?fopen(“test.txt”); ????if?(fh) ?????{ ?????????return;?//死鎖+內存泄露 ????} ????if?(fwrite(“abc”,?fh)?<?0) ?????{ ?????????return;?//死鎖+內存泄露+句柄泄露 ????} ????fclose(fh); ?????free(mem); ?????Unlock(mtex); }上述代碼中的資源泄露是顯而易見的,編程新手卻很容易寫出這樣的代碼,但問題卻不容易發現,因為異常流程通常不會發生,而一旦發生了,就是一場噩夢:不好跟蹤也不好重現。對吃過這種虧編程老手而言,處理起來會格外小心,而是有了如下版本的代碼(我們的工程中類似的代碼隨處可見):
void?fun() ? {Lock(mutex);mem?=?malloc(size); ????if?(null?==?mem) ?????{ ?????????Unlock(mutex);?//鎖解除了,很好 ????????return; ?????} ??fh?=?fopen(“test.txt”); ????if?(fh) ?????{ ?????????Free(mem); ?????????Unlock(mutext);?//錯誤處理加了一行 ????????return; ?????} ???if?(fread(mem,?size,?fh)?<?0) ?????{ ?????????Free(mem); ?????????Flcose(fh); ?????????Unlock(mutext);?//錯誤處理又加了一行… ????????return; ?????} ??fclose(fh); ?????free(mem); ?????Unlock(mtex); }?
這個版本的代碼沒什么邏輯問題,在每個異常環節,把該處理的都處理完了。看起來非常完美,卻依然存有大坑。首先,我們的異常處理流程越來越長,重復的代碼像火車車廂一樣越串越長,代碼維護非常不方便,某天其中一個異常處理流程要修改了,我們需要修同步多處,萬一漏了某處(事實上不是萬一,而是經常),問題沒有修改徹底;更為嚴重的是,冗于的異常處理會讓大家感到疲勞,某一天函數中又要加入新的資源引用或異常處理邏輯時,在先驅的引導下,我們的人依然還是會犯同樣的錯誤:要么什么都不管提前返回,或者處理不充分就走了,結果還是同樣的資源泄露。
如何解決,Linux內核代碼給了我們很好的解決方案,合理地使用goto語句,將異常處理定向到統一的地方,既解決了資源泄露隱患,也保持了正常流程代碼的簡潔性,這是改進后的版本:
void?fun() ?
{ ?????
? ? Lock(mutex);???
? ? mem?=?malloc(size); ????
? ? if?(null?==?mem) ?????
? ? { ?????????
? ? ? ? goto?ERR_EXIT1; ?????
? ? } ????
? ? fh?=?fopen(“test.txt”); ????
? ? if?(fh) ?????
? ? { ?????????
? ? ? ? goto?ERR_EXIT2; ?????
? ? } ????
? ? if?(fread(mem,?size,?fh)?<?0) ?????
? ? { ????????
? ? ? ? goto?ERR_EXIT3; ?????
? ? } ??
? ? ERR_EXIT3: ?????
? ? fclose(fh); ?
? ? ERR_EXIT2: ?????
? ? free(mem); ?
? ? ERR_EXIT1: ?????
? ? Unlock(mtex); ?
}
總結:以后新寫C代碼的異常處理,統一采用上面的模版。C++/java有更好的異常處理機制,上述方案只供參考,但解決思路應該是一致的,隨處return與冗余異常處理應該被嚴厲禁止。
?
總結
以上是生活随笔為你收集整理的return导致内存泄露。C函数中不要有多次return,以及其解决方法。goto的用法。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中ip经常改变解决(本人亲测,
- 下一篇: JAVA是纯什么编程语言_JAVA,语言