7

as of C++17 you can use make_unique in order to create smart pointers to arrays, such as:

unique_ptr<int[]> ptr = make_unique<int[]>(10);

which will create a smart pointer to an array of 10 elements (the fact that proper deleter[] will be called is also great).

However according to this make_shared does not support such functionality (at least not in C++17, to my understanding):

shared_ptr<int[]> ptr = make_shared<int[]>(10);

the code above is apparently illegal. Indeed, my Visual Studio 2017 (v141) spits out the following error:

C2070: 'int[]': illegal sizeof operand'

What's interesting is that shared_ptr itself does support array types (i.e., shared_ptr<int[]> is legal), but make_shared does not. Whereas make_unique does.

The question is, what prevented the standard maker people to let make_shared support array types, just like in the case of make_unique?

2
  • 5
    std::make_shared supports arrays from C++20 en.cppreference.com/w/cpp/memory/shared_ptr/make_shared Why not earlier, I suppose because someone has to write the proposal, advocate for it, get 1 or more implementations written etc. They probably had something else scheduled. Commented Aug 30, 2018 at 11:03
  • 5
    It was an oversight/deficiency in the c++14 and c++17 standards. It's in c++20. Commented Aug 30, 2018 at 11:03

1 Answer 1

2

What prevented the standard maker people to let make_shared support array types [...]?

Probably nothing, this case was simply not considered, similar to std::make_unique not being present in C++11 but added in C++14. And as pointed out in the comments, this missing piece will ship with C++20.

There is a difference between std::unique_ptr and std::shared_ptr that made neglecting raw arrays pointers easy, though: custom deleters are part of std::unique_ptr's type but not part of std::shared_ptr's type. Therefore, you can handle an array like this

std::shared_ptr<int> array = std::shared_ptr<int>(new int[10],
    [](int *ptr){ delete []ptr; });

and hence delegate the correct memory cleanup to the point of object creation. This makes it easy to treat raw arrays as a special case of std::shared_ptr instances.

Sign up to request clarification or add additional context in comments.

4 Comments

It appears, however, that as of C++17 shared_ptr<int[]> ptr(new int[10]) similarly invokes delete[] (see the link in the original question). Also, I did not encounter any memory leaks when declaring a shared pointer in such fashion. Please correct me if I am wrong.
Seems that this is something libstdc++ provides, independent of the language standard (tested with gcc-8 for -std=c++11/14/17), but not libc++ (tested with clang-6?!
@lubgr IIRC and everything I see here shows me that shared_ptr<int[]> ptr(new int[10]) should work fine in C++17. Pre C++17 you could also use std::unique_ptr<int[]> arr(new int[1]); std::shared_ptr<int> ptr(std::move(arr));
@NathanOliver You're right, I think I screwed up the flags for using the homebrew-up-to-date standard headers when testing. Should work with clang, too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.