日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

return导致内存泄露。C函数中不要有多次return,以及其解决方法。goto的用法。

發布時間:2024/1/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的用法。的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。