内存管理策略的问题
Problems with memory management strategy
在最新的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的资源韭菜。我说得对吗?
基本上,在上面的代码段中发生的是:
int* p = new int{7}; // probably should use a unique_ptr
int* buf = (int*)malloc(100*sizeof(int)); // C-style allocation
内存是通过C++new
和C
malloc分配的。这两个指针都不受管理,如果此时抛出任何代码,那么内存就会泄漏。但是,请注意,malloc
不会抛出,因此在隔离状态下,此代码是安全的。
http://en.cppreference.com/w/cpp/memory/c/malloc
auto act1 = finally([&]{ delete p;
free(buf); // C-style deallocation
cout<< "Goodby, Cruel world!n";
}
);
在这段代码中,一个RAII类型是从finally函数返回的。当act1
被销毁时(在异常或离开此范围时),它将执行可调用参数。
因为这直接遵循malloc
,所以我们现在已经确保了内存不会泄漏。
但是以下代码是不安全的:
int* p = new int{7}; // probably should use a unique_ptr
int* buf = (int*)malloc(100*sizeof(int)); // C-style allocation
throwing_function();
auto act1 = finally([&]{ delete p;
free(buf); // C-style deallocation
cout<< "Goodby, Cruel world!n";
}
);
然而Bjarne的评论很到位,只需使用std::unique_ptr
即可。
编辑:
最后使用:
database_handle dh1;
dh1.do("action...");
finally([&]{
if(!dh1.success()) {
dh1.rollback();
}
);
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 使用策略模式设计软件时出现的问题
- 基于策略的设计C++问题
- 内存管理策略的问题