Suppose we have a function to reveal our processing priority and a second function to do some processing on a dynamically allocated Widget in accord with a priority :
int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority);
However, we cannot use this function in this way:
processWidget(new Widget, priority());
Since tr1::std::shared_pointer's constructor taking a raw pointer is explicit, so there is no implicit conversion from the raw pointer returned by the expression new Widget to the tr1::shared_ptr required by processWidget.
So we should modify the code as:
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
Although it is using object-managing resources here, this call may leak resources.
Let us focus on the first argument,
std::tr1::shared_ptr<Widget>(new Widget)
it consists of two parts :
- Execution of the expression
new Widget. - A call to the
tr1::shared_ptrconstructor.
The new Widget expression must be executed before the tr1::shared_ptr constructor can be called because the result of the expression is passed as an argument to the tr1::shared_ptr.
But the call to priority can be performed everywhere. If the compilers choose to perform it second , we end up with this sequence of operations :
- Execute
new Widget. - Call
priority. - Call the
tr1::std::shared_ptrconstructor.
Since the call to priority may yields an exception ,the pointer returned from new Widget will be lost, because it will not have been stored in the tr1::shared_ptr we were expecting would guard against resource leaks.
The way to avoid problem like this is simple : use a separate statement to create the Widget and store it in a smart pointer, the pass the smart pointer to processWidget:
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());
Conclusion
Store new object in smart pointers in standalone statements.Failure to do this can lead to subtle resource leaks when exceptions are thrown.