Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ basic exception question

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.

like image 332
Yippie-Ki-Yay Avatar asked Feb 23 '23 10:02

Yippie-Ki-Yay


1 Answers

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.

like image 144
Alexandre C. Avatar answered Feb 27 '23 01:02

Alexandre C.