Problems with shared_ptr wrapping a dynamic array

后端 未结 4 1436
遇见更好的自我
遇见更好的自我 2021-01-13 02:08

I wanted to replace some raw pointers in my class with a std::shared_ptr so that I don\'t have to worry when I create copies of that class. But the raw pointers

相关标签:
4条回答
  • 2021-01-13 02:26

    If you insist that you should not use std::vector, Boost has a boost::shared_array that works as a smart pointer to manage a dynamically allocated array of object.

    shared_ptr is not designed to handle an array. Since shared_array is available, why try to use shared_ptr on array s?

    0 讨论(0)
  • 2021-01-13 02:34

    If you specified the deleter then you don't use T[] in the template argument. Just change T[] to T:

    template <typename T> shared_ptr<T> make_shared_array(size_t size)
    {
      return shared_ptr<T>(new T[size], default_delete<T[]>());
    }
    
    struct Foo
    {
      shared_ptr<char> field;
    };
    
    0 讨论(0)
  • 2021-01-13 02:45

    std::unique_ptr is specialized for array types so you can use T[] with it and it will know that it's still just storing a T*. std::shared_ptr is not specialized this way and so a shared_ptr<T[]> will try to store a pointer to an array, T(*)[], which won't work very well with the conventions around raw arrays in C++. Not to mention that an array of unknown size is an incomplete type, and shared_ptr will eventually need a complete type.

    You mention knowing that std::vector should be a better solution but doesn't perform as well. It should perform just fine and you'd probably be better off figuring out why it doesn't.

    0 讨论(0)
  • 2021-01-13 02:46

    The solution you suggest is possible, but you will lose the size of the array:

    #include <memory>
    #include <cstddef>
    
    using namespace std;
    
    template<typename T> shared_ptr<T> make_shared_array(size_t size)
    {
       return shared_ptr<T>(new T[size], default_delete<T[]>());
    }
    
    struct Foo
    {
      shared_ptr<char> field;
    };
    
    int main()  
    {
      Foo a;
      a.field = make_shared_array<char>(256);
    
     return 0;
    }
    

    What I have done here is to let the array decay into a pointer. As long as the deleter is an array deleter it should behave correctly.

    To prevent this loss of size, and if you cannot use boost::shared_array as suggested, I would suggest to encapsulate this information in your own shared_array class.

    0 讨论(0)
提交回复
热议问题