0

If you have a class that has a private shared_ptr defined in the header like so:

class myClass {
public:
  ...
private:
    std::shared_ptr<int> testint;
    void doSomething();
};

Later in doSomething (in myClass.cpp) what is the best way to initialize it?

void myClass::doSomething() {
    int i = getNumberFromFile("id.conf");
    testint(new int(i));                 // does not work
    testint.reset(new int(i));           //seems to work, but is this the right way?
    testint = std::make_shared<int>(i); // or is this better
}

Deduplicator: My question is what is the proper way to initialize a shared_ptr in a class function when the definition for the shared_ptr is in a the header file. Not what is the difference between using shared_ptr initialization and make_shared.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user846566
  • 373
  • 1
  • 3
  • 12

1 Answers1

2

This is the best

testint = std::make_shared<int>(12);

It has to be prefferred to:

std::shared_ptr<int> testInt(new int(12));

the reason is that it avoid extra copies and it can leak in one case:

if the allocation of the control block (which keeps track of the reference count) fails (in the library code), and throws, then there will be a memory leak of the int which was allocated with new in the user code.

Gabriel
  • 3,564
  • 1
  • 27
  • 49
  • How would an allocation failure result in a leak in this case? – juanchopanza Jan 02 '15 at 16:13
  • in this case no but with a large object it can happen (I will edit my post) – Gabriel Jan 02 '15 at 16:16
  • The size of the object has nothing to do with the possibility of a memory leak. – juanchopanza Jan 02 '15 at 16:17
  • I still don't understand why. Then I am curious why. just explain me why and then I will delete my post becuase if it is unaccurate. – Gabriel Jan 02 '15 at 16:19
  • @Deduplicator: The allocation for the control block can cause an exception to be thrown, in which case there will be a memory leak for the `new int`. – Benjamin Lindley Jan 02 '15 at 16:20
  • I am referring about that: http://stackoverflow.com/questions/18301511/stdshared-ptr-initialization-make-sharedfoo-vs-shared-ptrtnew-foo, see Mike Seymour answer. – Gabriel Jan 02 '15 at 16:20
  • 1
    *"if one exception is thrown when you call the new then you might leak"* -- This is either wrong, or it needs to be made a little more clear. It seems like you are saying that if the `new` (as in `new int(12)`) throws, then there will be a memory leak. There will not. However, if the allocation of the control block (which keeps track of the reference count) fails (in the library code), and throws, then there will be a memory leak of the `int` which was allocated with `new` in the user code. – Benjamin Lindley Jan 02 '15 at 16:31
  • ok corrected it with your changes. thks for the clarification I learnt something :-) – Gabriel Jan 02 '15 at 16:35
  • 2
    There is no (!) memory leak. See 20.7.2.2.1 shared_ptr constructors: Exception safety: If an exception is thrown, delete p is called. –  Jan 02 '15 at 16:50
  • The reason to prefer `make_shared` **here** is because it allocates the ref counts and the `int` in one go. In situations where you are constructing *multiple* `shared_ptr`s in an expression `make_shared` *also* ensures that nothing is leaked if an allocation fails, no matter what order the compiler picks for the subexpressions – Caleth Nov 21 '18 at 11:36