0

In C++11, I just found that it looks like there are some differences between shared_ptr and unique_ptr when they are used to allocate an array. I would like to get confirmation if what I found is correct.

I must use <int []> for unique_ptr but <int> for shared_ptr only:

unique_ptr<int []> myUniquePtr = unique_ptr<int[]> ( new int[100]);

shared_ptr<int> mySharedPtr = shared_ptr<int>( new int[100]);

For unique_ptr, I do not need to overload a delete functor/lambda func for a pointer to an array:

unique_ptr<int []> myUniquePtr = unique_ptr<int[]> ( new int[100]); //should be good enough

but I will for shared_ptr:

shared_ptr< int> mySharedPtr = shared_ptr<int> ( new int [100], [](const int* p){delete [] p;});

To access an element in the array through a smart pointer, with unique_ptr I can use the regular way [index], but with shared_ptr I cannot do that:

myUniquePtr[10] = 100; // should be OK

but I need

mySharedPtr.get()[10] = 100;

Could you please confirm if the above statements are correct? Will it be any different in C++14?

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
rudky
  • 89
  • 3
  • 2
    `uinque_ptr` has a specialisation for array types, wherefore it can discern whether it needs to use `delete`or `delete[]`without you providing the deleter. However, if you need to allocate an array and have the respective accessors, you probably want to use `std::vector` or `std::array` instead. – Christoph Sep 01 '18 at 16:32
  • You may want to look up `make_unique` and `make_shared`. – Jesper Juhl Sep 01 '18 at 17:55

1 Answers1

3

The different behaviour can be explained by the fact that there is a specialisation template <class T, class Deleter> class unique_ptr<T[], Deleter> for the std::unique_ptr. This specialisation allows for different behaviour when using an array type rather than a scalar type.

If you look at https://en.cppreference.com/w/cpp/memory/unique_ptr, you can also see that only the array variant implements operator [], which allows you to do the access described in 3.

If you take the documentation at https://de.cppreference.com/w/cpp/memory/shared_ptr, you see that there is no special handling for T[] in case of std::shared_ptr. Therefore, you need to retrieve the raw pointer before you can use the "standard" array access. Also, it cannot decide when to use delete and when delete[], so you need to provide a deleter if you do not pass an object that can be deleted by the standard deleter.

Afaik, there are no changes in this behaviour in C++14.

Christoph
  • 1,847
  • 2
  • 26
  • 41