0

I'm reading Scott Meyers' Effective C++ and he provided an example of a well-designed assignement operator. Here it is:

class Bitmap{ ... };
class Widget
{
    //...
private:
    Bitmap *pb;
};

Widget::operator=(const Widget& rhs)
{
    Bitmap *pOrig = pb;
    pb = new Bitmap(*rhs.pb);
    delete pOrig;
    return *this;
}

Now, the explanation he gives right after the example is about how the code is exception-safe.

Now, if new Bitmap throws an exception, pb (and the Widget it's inside of) remains unchaged)

I don't understand that. How can we ever talk about unchanging here if throwing execeptions by a constructor leads us to UB (because operator delete will no be called on the pointer return by the new operator which results in an exception) ?

Quentin
  • 62,093
  • 7
  • 131
  • 191
St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • Constructors are allowed to throw exceptions and this doesn't cause UB. Not sure what you are getting at in your last paragraph. When an exception is thrown, execution jumps to the `catch` handler for the exception, it does not continue onto `delete pOrig;` – M.M Jun 16 '15 at 04:32
  • @MattMcNabb As you can see, there is no any cathc clause in the example. So, the program will just be terminated.... – St.Antario Jun 16 '15 at 04:33
  • @St.Antario: How do you know there's no catch? The example is not a complete program. – Benjamin Lindley Jun 16 '15 at 04:34
  • @BenjaminLindley Well, there is no catch inside the operator= definition. Isn't that enough? – St.Antario Jun 16 '15 at 04:35
  • @St.Antario: Since there's no catch in the operator, the exception will be passed up the call stack. If there's no catch there, it will be passed up again, until you get to an appropriate catch, or until it is passed out of main, only then will a termination happen. – Benjamin Lindley Jun 16 '15 at 04:36
  • 1
    If the operator catches the exception inside, the caller can't tell if the assignment succeeded or not. That's why it's intentionally unhandled. – Amit Jun 16 '15 at 04:39
  • @BenjaminLindley So, we leave the exception handling to the client. That way, after throwing the exception, we passed out to the catch clause, therefore the original object remains unchanged. Do I understand it correctly now? – St.Antario Jun 16 '15 at 04:39

1 Answers1

2

If a constructor throws, operator new will not keep the memory allocated. This prevents the memory leak.

Note that a memory leak wouldn't be Undefined Behavior.

Community
  • 1
  • 1
MSalters
  • 173,980
  • 10
  • 155
  • 350