What does an default initialization of an array of shared_ptrs do?

388 views Asked by At

When I create an array of shared_ptrs to object Foo, what is actually being created?

class Foo {
public:
  Foo() x(3) : {};
  int x;
}

std::array<std::shared_ptr<Foo>, 10> arr_;

For instance, will the following code print 3?

std::shared_ptr<Foo> ptr = arr_[0];
std::cout << ptr->x;

Or do I first need to use make_shared and if so why?

std::shared_ptr<Foo> ptr = arr_[0];
ptr = make_shared<Foo>();
std::cout << ptr->x;
2

There are 2 answers

1
Sprite On

Constructs a shared_ptr with no managed object, i.e. empty shared_ptr. (ref)

So here's a small example to show that their default constructor stores nullptr.

#include <memory>
#include <array>
#include <iostream>

struct Foo {};

int main()
{
    std::array<std::shared_ptr<Foo>, 10> arr_;
    for (const auto &obj : arr_) {
        std::cout << obj.get() << '\n';
    }
}

Output

Program returned: 0
Program stdout
0
0
0
0
0
0
0
0
0
0

For instance, will the following code print 3?

No, it will dereference a nullptr and this is an undefined behavior (Usually, it is likely to cause a crash).

0
eerorika On

When I create an array of shared_ptrs to object Foo, what is actually being created?

Default constructed shared pointers will be created. Default constructed shared pointers are empty.

For instance, will the following code print 3?

There's no guarantee that it will. If you indirect through an empty shared pointer, the behaviour of the program will be undefined.

Or do I first need to use make_shared

That's a thing you can do.

and if so why?

Because if you don't create a Foo object, then you cannot access a Foo object.