Search code examples
c++c++11memory

Will smart pointer automatically release space hold by array?


If I apply memory by shared_ptr<double> p(new int);, the space applied will be automatically released once the use_count of p turns to 0. But if I apply for an array memory by shared_ptr<double> p(new int[10]);, will the whole array memory be released, or only the space of the first value is released(and cause potential memory leak)?

Matrix::Matrix(size_t m, size_t n) {
  shared_ptr<double> data_(new double[m * n]);
  m_ = m;
  n_ = n;
}

Solution

  • The default constructor of std::shared_ptr<double> will use a non-array delete expression as the deleter to destroy the managed object.

    Therefore passing the result of an array-new expression to it causes undefined behavior when the managed object is destroyed.

    Since C++17 you can use std::shared_ptr<double[]> instead which will by default use delete[] in the deleter and since C++20 there is also an overload for std::make_shared/std::make_shared_for_overwrite that can be used as std::make_shared<double[]>(m*n) to create the array and std::shared_ptr<double[]> managing it, so you don't need the manual new expression (which is something that should generally be avoided in most situations).

    With C++11 you need to provide a custom deleter that uses delete[] or wrap the array in a class type.

    Either way though, usually a std::vector<double> would be more appropriate than a std::shared_ptr<double[]> anyway. Consider whether you really need the shared ownership that shared_ptr provides (which is more often not the case). If you do, you can also use std::shared_ptr<std::vector<double>> instead (but that has one extra indirection).