假設我有一個下面的構造函數在C++類:投擲用C異常++時解放出來的本地緩存
MyClass::MyClass()
{
char* buffer = malloc(100);
if (0 != someD3DXCallThatCanFail(..., buffer, ...))
{
free(buffer);
throw MyException(L"some message");
}
char* buffer2 = malloc(200);
if (0 != anotherD3DCallThatCanFail(..., buffer2, ...))
{
free(buffer);
free(buffer2);
throw MyException(L"another message");
}
.. more code here where buffer and buffer2 are still used
free(buffer);
free(buffer2);
}
編輯:我不討厭的malloc /免費新/刪除,但不幸的是我需要使用緩衝區來加載紋理然後傳遞到ID3D10ShaderResourceView,ID3D10Buffer,頂點緩衝區等。所有這些都需要指向緩衝區的指針。
我正在嘗試使用異常而不是返回錯誤代碼。 我也希望在需要時創建緩衝區,並在不再需要它們時立即釋放它們。
但是,看起來很醜陋的是,如果發生錯誤,無論我返回錯誤代碼還是拋出異常,我仍然應該記住清理在此之前創建的任何緩衝區。如果我有10個緩衝區和10個可能的錯誤點,我將不得不調用free()100次(在每個錯誤情況下記住釋放每個緩衝區)。
現在假設我或者更糟,我的同事想要改變一些邏輯,比如說在中間的某個地方添加另一個緩衝區。現在,他必須查看通過該方法其餘部分可能發生的所有錯誤,並在每個這樣的地方爲該緩衝區添加free()。如果他很匆忙,他可以輕鬆地忽略幾個這樣的地方,並且你有內存泄漏。
這也使得代碼非常龐大。
finally關鍵字可以解決Java或C#中的問題。無論代碼在哪裏發生異常,我仍然會在「finally」中清除所有這些緩衝區(順便說一句,你不需要垃圾回收)。在我所瞭解的C++中,我可能必須爲任何這樣的緩衝區創建一個成員變量,並且在析構函數中確保緩衝區被清除。看起來對我來說也很難看,因爲一個名爲「pBuffer」的成員變量,即使是私有成員變量也僅僅是垃圾,因爲它只用於一個方法(在這種情況下是構造函數),並且將始終爲NULL,剩下的時間。
必須是一個常見問題,但我沒有設法使用搜索找到答案。謝謝!
除非絕對必要,否則應該避免在C++中使用'malloc/free'的習慣。優先使用'new/delete'。 –
確實,但不希望使用'new/delete' :)使用容器,智能指針等來避免手動管理內存。他們使保證異常安全變得更容易。 –
@Dave - 一旦你這樣做,避免使用智能指針'new'和'delete'來獲得更簡單的生活 –