Could someone please describe what's the correct way to handle the following situation:
wchar_t* buffer = new wchar_t[...];
if (!something)
{
throw std::runtime_error("Whatever");
// Now, at this point I'm leaking memory allocated for the 'buffer'.
}
// Perform actions.
delete[] buffer;
The obvious way to solve it means something like:
if (!something)
{
delete[] buffer;
throw std::runtime_error("Whatever");
}
Now - is it fine? (I suspect so, but who knows :)
P.S I do realize that there is a much better way to do it - using, boost::scoped_array
or simply std::wstring
, which allows the destructors called to release the allocated memory, just being curious.
Your insight is right. The pattern
Acquire some resource
Do something
Release resource
is fundamentally wrong, since Do something
can potentially throw an exception and leak the resource. Moreover, you have to remember to release the resource, which is a fertile source of errors.
The correct way, as you point, is to always use an object whose destructor releases the resource. This goes by the name of RAII in C++.
This means eg. never using delete
outside destructors, or never rely on manually closing file handles, never unlock mutexes manually, etc. Learn about smart pointers, and use them whenever you can.
Note that some languages (not C++) provide a finally
keyword, which permits you to execute a block of instructions irrespectively of whether an exception is thrown. C++ uses RAII, and you should never be concerned with resource release if you write proper destructors.
I have a little utility there for C++0x which allows execution of arbitrary code at block exit, should you interface once or twice with poorly written (or C) libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With