3

To allocate a char* array I would normally write something like:

char* arr = new char[size];

How can I achieve the same thing using boost::shared_ptr (or probably boost::shared_array) and boost::make_shared?

My guesses are:

1) boost::shared_ptr<char[]> arr = boost::make_shared<char[]>(size);

2) boost::shared_ptr<char> arr = boost::make_shared<char>(size);

3) boost::shared_ptr<char> arr = boost::shared_ptr<char>(new char[size]);

The last one looks right but is it guaranteed that upon destruction delete [] arr will be called?

user2735714
  • 131
  • 7
  • Your question asks about allocating a "char* array", but what you really want is a char array. Do you really want an array of pointers? (And once you realize that, 3 is clearly wrong. It creates a smart pointer whose type says it's to a `char`, not an array of anything. – David Schwartz Oct 06 '17 at 21:52
  • So the correct one is 1) ? I thought that 3 declares a pointer to an array because of new char[size]. In other words I expect it to be a pointer to the first character of the array, which is followed by size-1 chars. – user2735714 Oct 06 '17 at 22:04
  • But what you wanted was a smart pointer to an array, that points to the first character in the array. You didn't want a smart pointer to a character that happens to point to the first character in the array. So the *type* is wrong, even though it points to the right thing. – David Schwartz Oct 06 '17 at 22:07
  • Ok so 1) is the correct one? And when the object is destructed delete [] arr will be called not delete arr, right? – user2735714 Oct 06 '17 at 22:17
  • 1
    The support is documented [here](http://www.boost.org/doc/libs/1_60_0/libs/smart_ptr/make_shared_array.html). It's not guaranteed that `delete[]` will be used specifically (if you think about it, that would be inefficient as you'd need a separate object to hold the returned value), but the objects will be properly destructed and the memory freed. – David Schwartz Oct 06 '17 at 22:20
  • Another interesting thing is when shared_array should be preferred to shared_ptr. – user2735714 Oct 06 '17 at 22:30

2 Answers2

2

The correct one is make_shared<T[]>(n).

Bear in mind that pre-c++20 it's an extension not present in the standard library (although unique_ptr<T[]> is part of the standard).

Boost's shared_ptr will indeed call the correct deleter (naively, delete[]) for it.

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    Correcting sehe's statements slightly, the make_shared() specialization was overlooked and omitted from the '11 and '14 standards, but has been added to the '17 standard. – jschmerge Oct 07 '17 at 04:05
  • @jschmerge thanks for the addition. I added the _corrected_ addition to the answer :) (Perhaps the details of when it'll be added aren't official yet) – sehe Oct 07 '17 at 11:09
2

Boost shared_ptr and make_shared

Boost supports array allocation and handling using shared_ptr and make_shared. According to boost's docs:

Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamically allocated array. This is accomplished by using an array type (T[] or T[N]) as the template parameter. There is almost no difference between using an unsized array, T[], and a sized array, T[N]; the latter just enables operator[] to perform a range check on the index.

Just use:

shared_ptr<char[]> arr(new char[size]);
-- OR --
shared_ptr<char[]> arr = make_shared<char[]>(size);

Standard library

According to cppreference.com, The standard shared_ptr, make_shared and allocate_shared added support for arrays starting from C++20.

Daniel Trugman
  • 8,186
  • 20
  • 41