Harold Serrano

View Original

C++ tip 11: Store newed objects in smart pointers in standalone statements

This weekend I spend my Saturday working on my game engine and as a break I decided to learn a new tip from Scott Meyers' book Effective C++. I came across a very illuminating tip. Something that I would have never thought about.

This is what Scott Meyers says:

Suppose you have two functions. One in charge of setting the priority level and the other to process a particular widget. For example:

int priority();
void processWidget(std::tr1::shared_ptr<widget> pw, int priority);

You may think that calling the function processWidget() as shown below would not result in any memory leaks.

processWidget(std::tr1::shared_ptr<widget>(new Widget) , priority());

You are wrong!!! The above statement may produce a leak even though we are using objects to manage resources.

According to Scott Meyers here is why:

Before the function processWidget() can be called, it must generate code to do these three things:

  • Call priority
  • Execute new Widget
  • Call the tr1::shared_ptr constructor

In any other language, the function parameters are always executed in a particular order. However, in C++ this is not the case.

For example, in the example above, the C++ compiler can generate the following order of execution:

  • Execute new Widget
  • Call priority
  • Call the tr1::shared_ptr constructor

Now, imagine if the call to priority() generates an exception. In that case, the pointer returned by new Widget will be lost and it would never be stored in the tr1::sharedptr_ object. Thus, generating a leak!!!

So what does Scott Meyers suggest you should do?

Store newed objects in smart pointers in standalone statements.

This means to use a separate statement to create the Widget and store it in a smart pointer, then pass the smart pointer to the processWidget function. This is shown below:

std::tr1::shared_ptr<widget> pw(new Widget); //store newed object in smart pointer

processWidget(pw,priority()); //this will not cause a leak

I think this is a very nice tip from Effective C++. I hope you find it helpful.

Sign up to my newsletter below and receive tips on game engine development and C++.