ZijingWu
ZijingWu

Reputation: 3500

Is there might be memory leak to allocate shared_ptr on the heap?

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

Answers (4)

masoud
masoud

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

InsertMemeNameHere
InsertMemeNameHere

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

Mike Seymour
Mike Seymour

Reputation: 254771

If the allocation of shared_ptr throw bad_alloc exception and the new int has been evaluate, I assume the int 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 parameter new 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

svk
svk

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

Related Questions