在最新的C++編程語言書中,Bjarne提出了一種正統錯誤處理的替代方案,即使用異常。這是章13.3.1,他寫道:內存管理策略問題
void test()
// handle undiciplined resource acquisition
// demonstrate that arbitrary actions are possible
{
int* p = new int{7}; // probably should use a unique_ptr (§5.2)
int* buf = (int*)malloc(100*sizeof(int)); // C-style allocation
auto act1 = finally([&]{ delete p;
free(buf); // C-style deallocation
cout<< "Goodby, Cruel world!\n";
}
);
int var = 0;
cout << "var = " << var << '\n';
// nested block:
{
var = 1;
auto act2 = finally([&]{ cout<< "finally!\n"; var=7; });
cout << "var = " << var << '\n';
} // act2 is invoked here
cout << "var = " << var << '\n';
}// act1 is invoked here
雖然我明白他試圖解釋,什麼該代碼應該實現的,我有問題,認爲這片段是免費韭菜:
> 1. int* p = new int{7}; // probably should use a unique_ptr (§5.2)
> 2. int* buf = (int*)malloc(100*sizeof(int)); // C-style allocation
>
>
> 3. auto act1 = finally([&]{ delete p;
> free(buf); // C-style deallocation
> cout<< "Goodby, Cruel world!\n";
> }
> );
爲什麼? 因爲如果在第二行(2)我們得到異常拋出(假設沒有調用一個malloc而是一個可以實際拋出的函數,因爲我相信Bjarne試圖解釋的概念是使用finally構造這裏的malloc調用是不相關的,偶然的,可以被任何調用取代),那麼如果兩個拋出然後3永遠不會到達,我們有資源韭菜從1 我是否正確?
如果這就像一個的malloc函數拋出一個異常,但這樣做之前,所以分配一些內存它不那麼自由,那麼它是非常很調皮。爲什麼要承擔這樣的事情?沒人理智會寫,imo。如果它拋出異常,沒有人會知道你將不得不釋放的內存地址。 – polkadotcadaver
儘管如此,如果在內存分配和「finally」對象創建之間引發異常時忽略這一點,那麼會出現泄漏。 – polkadotcadaver
@polkadotcadaver:泄漏不會出現在* buf中,而是出現在* p中。 –