1

According to this paper, one of the common mistakes developers make ( #3 ) is using a smart pointer with array types; Mainly because the operator delete will be called instead of delete[], leaving the program with a memory leak.

Depite that; looking up default deleter in the C++ reference, the following code is there:

#include <memory>
#include <vector>
#include <algorithm>
 
int main()
{
//  {
//      std::shared_ptr<int> shared_bad(new int[10]);
//  } // the destructor calls delete, undefined behavior
 
    {
        std::shared_ptr<int> shared_good(new int[10], std::default_delete<int[]>());
    } // the destructor calls delete[], ok
 
    {
        std::unique_ptr<int> ptr(new int(5));
    } // unique_ptr<int> uses default_delete<int>
 
    {
        std::unique_ptr<int[]> ptr(new int[10]);
    } // unique_ptr<int[]> uses default_delete<int[]>
 
    // default_delete can be used anywhere a delete functor is needed
    std::vector<int*> v;
    for(int n = 0; n < 100; ++n)
        v.push_back(new int(n));
    std::for_each(v.begin(), v.end(), std::default_delete<int>());
}

Which directly contradicts that; But this might be because of different C++ standards; Is this the case, or is #3 in the paper simply untrue?

Does a deleter needs to be provided explicitly when using arrays with smart pointers, or does it depend on the c++ standard ( e.g. different behaviour in C++11 or c++17; c++20 ); or the platform (e.g. gcc, MSVC etc.. )?

Dávid Tóth
  • 2,788
  • 1
  • 21
  • 46
  • 1
    The paper says: "If using of a smart pointer is required for an array, it is possible to use -- a unique_ptr specialization." There seems to be no contradiction here. – VLL Mar 09 '22 at 09:24
  • The usual/idiomatic dynamic array should be `std::vector`. It does not mean `unique_ptr` (similar case for shared_ptr) cannot be used, one should simply be aware of how to use it (note the brackets in `T[]`), and, more importantly, why was it chosen in the first place over other, library-provided data structures. – alagner Mar 09 '22 at 09:28
  • The #3 case is shown in the code sample. It is the first sample that is commented out and, if not commented out, would give undefined behaviour. It is actually a fairly common mistake made when using `shared_ptr` (or `unique_ptr`). – Peter Mar 09 '22 at 09:33

1 Answers1

1

If I understand correctly, you seem to think that the example 4 contradicts the paper, and the paper recommends using example 2. This is not what the paper is saying.

Example 1 is undefined behavior, as described in the paper: "Using smart pointers, such as auto_ptr, unique_ptr, shared_ptr, with arrays is also incorrect."

Example 2 works correctly, however using a custom deleter is not mentioned in the paper at all.

Example 3 creates pointer to single int. This is not related to the paper.

Example 4 creates pointer to int[], which is mentioned in the paper as a valid usage: "If using of a smart pointer is required for an array, it is possible to use -- a unique_ptr<T[]> specialization."

VLL
  • 9,634
  • 1
  • 29
  • 54