7

I was wondering why dynamic arrays are directly supported by std::unique_ptr<> but not by std::shared_ptr<>:

unique_ptr<int[]> ptr1(new int[n]); /// OK!
shared_ptr<int[]> ptr2(new int[n]); /// Incorrect: will not call delete[]

Update: I found out that the second line can be rewritten as:

 shared_ptr<int> ptr2(new int[n], default_delete<int[]>());

Now I am wondering what's going on behind the scene that makes std::shared_ptr works with the second approach and not in the way similar to std::unique_ptr?

Vahid Noormofidi
  • 748
  • 10
  • 17
  • What error message do you get? – Chris Beck Sep 22 '15 at 22:20
  • It's not about error message, it's about the correctness of the second line since it does not invokes delete[] – Vahid Noormofidi Sep 22 '15 at 22:26
  • Don't you have to specify a deleter with `unique_ptr` (i.e. the `deleter` template parameter has no default)? That at least is what is suggested [here](http://en.cppreference.com/w/cpp/memory/unique_ptr) if am not mistaken. – Walter Sep 22 '15 at 22:30
  • Is your question essentially why there is a `unique_ptr` specialisation, but no `shared_ptr` specialisation? – Walter Sep 22 '15 at 22:31
  • @Walter yes! I'm wondering what's the technical reason? – Vahid Noormofidi Sep 22 '15 at 22:32
  • Wellcome on stackoverflow! Good question. – Walter Sep 22 '15 at 22:37
  • @Vahid: Well, anyways, when you say that some code is incorrect on stackoverflow, unless its specifically a language lawyer question, it's a good idea to put the error message to help people figure out what's wrong. If you think your question is a language lawyer question you can tag it as such. (Even in a language lawyer question they give some kind of explanation usually. You've since modified this question so its someone moot now :) ) – Chris Beck Sep 22 '15 at 23:03
  • 2
    There is such specialization, in the [library fundamentals TS](https://rawgit.com/cplusplus/fundamentals-ts/v1/fundamentals-ts.html#memory.smartptr.shared.obs). – cpplearner Sep 22 '15 at 23:26
  • ... except that it is named `std::experimental::shared_ptr`. – cpplearner Sep 22 '15 at 23:30
  • 1
    See the second half of https://stackoverflow.com/a/13062069/241631 – Praetorian Sep 23 '15 at 04:48

1 Answers1

3

With shared_ptr you have to use a custom deleter that invokes delete[], if you allocate the array with new[].

Also, you have to be careful with up- and down-casting just as with raw pointers, so as not to invoke Undefined Behavior.

unique_ptr has direct support for arrays, so that when it knows that it holds a pointer to array you can't up- or down-cast, and the default deleter invokes delete[].

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 3
    I understand that, but is it due to a limitation of shared_ptr that it cannot utilize delete[] ? – Vahid Noormofidi Sep 22 '15 at 22:25
  • 1
    @Vahid: `shared_ptr` came from the Boost library, which also has [`shared_array`](http://www.boost.org/doc/libs/1_59_0/libs/smart_ptr/shared_array.htm). It's arguably a more clean division than the specializations of `unique_ptr`. But it means that `shared_ptr`, by design, doesn't actively support arrays. You have to cajole it into it, e.g. by using a custom deleter. – Cheers and hth. - Alf Sep 22 '15 at 22:34
  • So, the reason is because of compatibility with the Boost lib, and because the `shared_array` has not been ported to STL yet, right? – Vahid Noormofidi Sep 22 '15 at 22:42