SFML community forums

Help => General => Topic started by: Azaral on January 23, 2014, 07:02:14 pm

Title: Passing new and storing in a smart pointer safe?
Post by: Azaral on January 23, 2014, 07:02:14 pm
Is this safe or should I pass std::unique_ptr instead of using new?


void Function( Object* object )
{
     myObjects.push_back( std::unique_ptr< Object >( object ); //myObjects is a vector of std::unique_ptr< Object >
}

Function( new object );

 

Or would this be better?


void Function( std::unique_ptr< Object > object )
{
     myObjects.push_back( std::move( object ) ); //myObjects is a vector of std::unique_ptr< Object >
}

Function( std::unique_ptr< Object >( new object ) );

 

I ask because I just started making use of smart pointers and want to make sure I'm doing it right.
Title: Re: Passing new and storing in a smart pointer safe?
Post by: Lo-X on January 23, 2014, 07:12:03 pm
I would go for the second one. Even if the risks are low, it's always there. So there is no reason not to use smart pointers from the start.

Nexus just wrote an article about RAII/Smart pointers : http://www.bromeon.ch/articles/raii.html
Title: Re: Passing new and storing in a smart pointer safe?
Post by: Azaral on January 23, 2014, 07:15:38 pm
Yeah, I read that article (reading Nexus' view on smart pointers was what got me to use them actually), but it doesn't mention what I'm asking here AFAIK.
Title: Re: Passing new and storing in a smart pointer safe?
Post by: Nexus on January 23, 2014, 08:49:39 pm
You're doing it right in the second code. There is however a potential probem with temporary smart pointers if multiple ones are used:
Function2(std::unique_ptr<A>(new A), std::unique_ptr<B>(new B));

This code is not exception-safe, because order of execution of the expression parts is not determined by the standard. A compiler is allowed to execute first new A and then new B, and only then call the unique_ptr constructors. If the B constructor throws an exception, then you have a memory leak, because the A object is never deleted. One way to fix the problem is to use local variables instead of temporary expressions.

If your compiler already supports that, you can also use std::make_unique():
Function( std::make_unique<Object>() );

Since it encapsulates the call to the new operator, it nicely solves the exception issue.
Title: Re: Passing new and storing in a smart pointer safe?
Post by: Azaral on January 23, 2014, 09:12:51 pm
Thank you Nexus.