在最新的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中。 –