Reputation: 3500
Just read this SO post stdshared-ptr-exception-safety
So following code will not have memory leak:
std::shared_ptr<int> p3 (new int);
But how about following one:
func(new std::shared_ptr<int>(new int));
If the allocation of shared_ptr
throw bad_alloc
exception and the 'new int' has been evaluate, I assume the int
be leaked.
Does they standard defined the new std::shared_ptr
need to first allocate memory and then evaluate the parameter new int
?
Upvotes: 2
Views: 2471
Reputation: 56549
It can lead to memory leak and it's unsafe. The allocated std::shared_ptr
itself, should be protected somewhere. shared_ptr
may throw an exception and you should handle it. new std::shared_ptr
also can throw an exception and you should handle it too. The first exception doesn't lead to memory leak, but the second dose.
On the other hand, you don't need to allocate a std::shared_ptr
dynamically; it has no advantages.
Upvotes: 0
Reputation: 2433
Yes, it can leak.
If new std::shared_ptr
throws, there is nothing to clean up the memory allocated by new int
.
In general, automatic delete
invocations are made only when a constructor throws after a corresponding new
.
To elaborate, you can rewrite the code as follows:
// if 'new' throws, we just get a bad_alloc, nothing leaked
int *iptr = new int;
// if 'new' throws, nothing will clean up iptr
//
// if, for whatever reason, ctor of std::shared_ptr<int> throws,
// its memory gets reclaimed by an implicit delete, but iptr's target
// is still lost.
auto *ptrptr = new std::shared_ptr<int>(iptr);
// EDIT: If the constructor of shared_ptr fails, it will delete
// the memory it is given, though this still doesn't eliminate the
// leak that can occur if the above `new` fails.
EDIT:
The example above, and this explanation, were really meant to indicate that there isn't anything special about std::shared_ptr
as compared to any other smart pointer implementation, or some type that accepts a pointer as a constructor argument for that matter.
In the latter case, it really depends on what the type's constructor does with its argument. In the case of std::shared_ptr
, it most likely will not throw an exception unless it fails to allocate a control block (if that is, in fact, how it is implemented).
If the constructor of std::shared_ptr
does fail, at least with the implementation I am using (VS2012), it actually does delete the memory it is given.
Upvotes: 2
Reputation: 254771
If the allocation of
shared_ptr
throwbad_alloc
exception and thenew int
has been evaluate, I assume theint
be leaked.
Yes, if the evaluations happen in that order, and the allocation for the shared pointer fails, then the integer will be leaked.
Does they standard defined the
new std::shared_ptr
need to first allocate memory and then evaluate the parameternew int
?
No, they are indeterminately sequenced, as specified in C++11 5.3.4/16.
So dynamic allocation of smart pointers is dangerous, not just weird and confusing. Don't do it.
Upvotes: 2
Reputation: 5919
Yes, that's a potential memory leak.
However, it's a very unconventional use of std::shared_ptr
. Generally the shared_ptr
is kept in automatic storage (on the stack) to take advantage of RAII.
Upvotes: 4