It is safe to use vector.emplace_back (new MyPointer); Can a failure inside a vector lead to a memory leak?

Is it safe to use

vector.emplace_back( new MyPointer() ); 

Or can an exception or some kind of failure inside the vector cause a memory leak?

It would be better to do some form of the following, where you first put the pointer in temporary unique_ptr.

 vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) ); 

So, if a vector crashes, will temporary unique_ptr still clear the memory?

+7
c ++ memory-leaks c ++ 11 stdvector
source share
2 answers

It is not safe and will create a memory leak if you use the first version. The documentation says that if an exception is thrown, calling emplace has no effect - this means that the simple pointer you passed in is never deleted.

you can use

 vector.emplace_back( std::unique_ptr<MyPointer>( new MyPointer() ) ); 

or with c ++ 14 you can use

 vector.emplace_back( std::make_unique<MyPointer>() ); 

or, if C ++ 14 is not yet available, just flip your own version of make_unique . Here you can find.

+11
source share

No, the first scenario is unsafe and there will be a memory leak if vector throws an exception.

The second script will not compile, since std::unique_ptr<T> cannot be implicitly converted to T* . Even if it’s possible, this scenario is probably worse than the first because it will add a pointer to your vector and then immediately delete the object that it points to. You will be left with a vector containing a dangling pointer.

Without changing the type of your std::vector (which I assume std::vector<MyPointer*> ) there are two ways to make this code safe.

Using C ++ 11:

 auto ptr = std::unique_ptr<MyPointer>(new MyPointer()); vector.emplace_back(ptr.get()); ptr.release(); 

Or a more detailed C ++ 03 way:

 MyPointer* ptr = new MyPointer(); try { vector.push_back(ptr); } catch (...) { delete ptr; throw; } 

If you can change the type of your std::vector<MyPointer*> , then the easiest way are the methods suggested by Daniel Frey above:

 std::vector<std::unique_ptr<MyPointer>> vector; vector.emplace_back(std::unique_ptr<MyPointer>(new MyPointer())); 

Or with C ++ 14:

 std::vector<std::unique_ptr<MyPointer>> vector; vector.emplace_back(std::make_unique<MyPointer>()); 
+2
source share

All Articles