1

As wiki shows, shared_ptr can handle the heap space recycle problems. So, I always use shared_ptr to create instance, is there any problems?

and I use it as this, i dont need to delete s, right?

s = std::shared_ptr<S>(new S).get();
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
nick huang
  • 443
  • 4
  • 12
  • 5
    Those are not your only two options. A naked `new` is rarely the best choice but you have other memory managing helpers. `std::unique_ptr` is often useful. If you have a lot of objects you can often leave the management to a [container](https://en.cppreference.com/w/cpp/container) etc. It depends of what you want to accomplish. – Ted Lyngmo May 25 '19 at 14:29
  • 2
    Well, you don't have to delete `s` in your example, it will be deleted for you right in the same line. `std::shared_ptr(new S)` creates temporary `shared_ptr` which lives for the time of expression evaluation and you don't assign it to any variable. So it get's destroyed right away. `shared_ptr` does not "handle the heap space recycle problems" magically, you still have to use it properly. Maybe unique_ptr is better? But the topic is too broad for comment or single answer. I'd recommend starting here: https://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one – R2RT May 25 '19 at 14:33
  • Use `unique_ptr` unless you actually need shared ownership. – Shawn May 25 '19 at 14:37
  • C++ `shared_ptr` mimics the shared reference semantics of Java or C#, but in my experience with C++ it is much better to have a stricter ownership mode. I recommend `unique_ptr` where possible, and `shared_ptr` if you *need* it rather than as your first option. – Eljay May 25 '19 at 14:38
  • Do you actually need a pointer at all? Do `S s;` by default, unless you actually need it on the heap for some reason. – Nikos C. May 25 '19 at 14:42

1 Answers1

3

You shouldn't always use shared_ptr because there are more types of smart pointer than just shared_ptr. The Standard Library also provides unique_ptr for example. You must evaluate which better suits the task at hand.

Smart pointers in general are however the preferred way of safely handling dynamically allocated objects in modern C++. As a general rule of thumb, avoid the use of new and delete unless you encounter a problem that can't be solved without them.

As an aside, your example will not work as you expect.

auto s = std::shared_ptr(new S).get();

This will create a dangling pointer. The call to new dynamically allocates an object of type S. A pointer to it is given to the constructor for shared_ptr which now manages the object lifetime. You then assign a copy of the raw pointer of S to s via get(). At the end of the line the shared_ptr destructor frees S meaning that whatever s points to is undefined.

The correct way to create a shared pointer would be:

auto s = std::make_shared<S>();
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Fibbs
  • 1,350
  • 1
  • 13
  • 23
  • no new S in the brackets? and to get the instance, i should use s.get()? – nick huang May 25 '19 at 14:39
  • You don't need to use `new` because `make_shared` does it internally, you're just telling the template what type the smart pointer should hold. The main benefit of letting the library handle it is that `shared_ptr`'s control block and the object itself will be allocated together. If you call the shared_ptr constructor with `new` you'll end up with the control block and object potentially allocated to different parts of the heap. Calls to `get()` are useful in some situations, for example if you need the raw pointer to pass to a C function. – Fibbs May 25 '19 at 14:47