Reputation: 33
So, I have a question, the answer to which I could not find. In C++ shared pointer has a constructor that can contain a raw array(std::shared_ptr<int[]>,for example.)
What are the benefits of using it compared to std::array or std::vector?
Tried to search, ask gpt. As for std::vector, there is a suggestion that memory allocation can be avoided with std::shared_ptr, but that doesn't explain why using this when there is a std::array
Upvotes: 3
Views: 149
Reputation: 409
Use of containers and smart pointers depends on usage and design:
std::vector creates a dynamic array of objects on heap
std::array creates a static array of object on stack, size known at compile time
std::shared_ptr<int[]> keeps the reference count of the resource, here resource is a pointer to an array
std::array is on the stack, if usage is limited to a scope and size is known at compile time then array is fine.
when you want to share the ownership of the resource across functions, containers, thread(multi-thread safe object or const), shared_ptr is suitable. But using shared_ptr doesnt mean we can avoid allocation, you need to pass a resource pointer which it manages.
As for vector, it allocates data on heap but need to take care that vector itself should not go out of scope otherwise destructor will free up the resource as it doesnt have refrence count like shared_pointer.
If you use vector ,atleast one allocation is done.
If you use array, its on stack so no allocation is done.
shared_ptr takes a pointer, which has to be allocated somewhere. other allocation is of control block. thus 2 allocation until std::make_shared is used which can optimize the number of allocations.
Upvotes: 1
Reputation: 96013
Unlike all other listed options, std::array
requires the size to be known at compile-time, and doesn't store the elements on the heap (unless it itself is on the heap).
std::vector<T>
can work with a size not known at compile-time, and should be your default choice in that case. It always stores the elements on the heap.
std::unique_ptr<T[]>
can be thought of as a stripped down std::vector
. It doesn't know its size, which saves a tiny bit of memory (sizeof(std::unique_ptr<T[]>)
is normally sizeof(void *)
, while sizeof(std::vector<T>)
is normally 3 * sizeof(void *)
).
Because it doesn't store its size, there's very few things it can do out of the box: it can't be copied (only moved), it can't insert or remove elements, etc. You can do all of this manually if you store the size separately, but then it's just std::vector
with extra steps.
std::shared_ptr<T[]>
adds an extra feature to std::unique_ptr<T[]>
- shared ownership, like any other std::shared_ptr<??>
.
Upvotes: 5