Kra*_*Kra 24 c++ try-catch delete-operator
我希望有一个简单的问题 - 当异常发生时,如何在try块中分配一个空闲内存?请考虑以下代码:
try
{
char *heap = new char [50];
//let exception occur here
delete[] heap;
}
catch (...)
{
cout << "Error, leaving function now";
//delete[] heap; doesn't work of course, heap is unknown to compiler
return 1;
}
Run Code Online (Sandbox Code Playgroud)
如何在分配堆之后释放内存并在调用之前发生异常delete[] heap?在这些try .. catch块中是否有规则不在堆上分配内存?
sta*_*ica 34
研究RAII习语(资源获取是初始化)!参见例如关于RAII的维基百科文章.
RAII只是一般的想法.它用于例如C++标准库std::unique_ptr或std::shared_ptr模板类中.
对RAII成语的简要解释:
基本上,它是try..finally在其他一些语言中找到的块的C++版本.RAII成语可以说更灵活.
它的工作原理如下:
您在资源周围编写了一个包装类(例如内存).析构函数负责释放资源.
您可以在作用域中创建包装类的实例作为本地(自动)变量.一旦程序执行离开该范围,将调用对象的析构函数,从而释放资源(例如内存).
重要的一点是,范围如何退出并不重要.即使抛出异常,仍然会退出作用域,仍然会调用包装器对象的析构函数.
很粗糙的例子:
// BEWARE: this is NOT a good implementation at all, but is supposed to
// give you a general idea of how RAII is supposed to work:
template <typename T>
class wrapper_around
{
public:
wrapper_around(T value)
: _value(value)
{ }
T operator *()
{
return _value;
}
virtual ~wrapper_around()
{
delete _value; // <-- NOTE: this is incorrect in this particular case;
// if T is an array type, delete[] ought to be used
}
private:
T _value;
};
// ...
{
wrapper_around<char*> heap( new char[50] );
// ... do something ...
// no matter how the { } scope in which heap is defined is exited,
// if heap has a destructor, it will get called when the scope is left.
// Therefore, delegate the responsibility of managing your allocated
// memory to the `wrapper_around` template class.
// there are already existing implementations that are much better
// than the above, e.g. `std::unique_ptr` and `std::shared_ptr`!
}
Run Code Online (Sandbox Code Playgroud)
好先生Java程序员:
try
{
// Exception safe dynamic allocation of a block of memory.
std::vector<char> heap(50);
// DO STUFF
// Note in C++ we use stack based objects and their constructor/destructor
// TO give a deterministic cleanup, even in the presence of exceptions.
//
// Look up RAII (bad name for a fantastic concept).
}
catch (...)
{
cout << "Error, leaving function now";
return 1; // Though why you want to return when you have not fixed the exception is
// slightly strange. Did you want to rethrow?
}
Run Code Online (Sandbox Code Playgroud)
一般的答案是使用RAII.
但是,可以通过将变量移出try {}范围来解决它:
char * heap = NULL;
try {
heap = new char [50];
... stuff ...
} catch (...) {
if (heap) {
delete[] heap;
heap = NULL;
}
... however you want to handle the exception: rethrow, return, etc ...
}
Run Code Online (Sandbox Code Playgroud)
请注意,我不建议将此作为一种良好的做法 - 但只有在您真正了解风险且仍愿意接受风险的情况下才能使用它们.就个人而言,我会使用RAII.
和平
要么移动new之前try,指针仍在范围内,要么使用类似的智能指针shared_ptr或unique_ptr(在紧要关头auto_ptr,但它有问题)将在退出时为您清理.例外是智能指针很重要的一个重要原因.