Moustapha Ramadan
Moustapha Ramadan

Reputation: 109

C++ struct of pointers crash, when initialized without {}

While refactoring a C-style struct to C++, I am facing a crash when creating a new object of the struct without {}.

I have illustrated the problem with the following code snippet.

struct A {
    A() = default;
    int* a1;
    int* a2;
};

int main()
{
    A a{};
    std::cout << a.a1 << std::endl; //print 0000000000000000(nullptr)

    A b;
    std::cout << b.a1 << std::endl; //crash (0xcccccccccccccccc)
}

Why a.a1 is initialized to nullptr while b.a1 is not nullptr?

What is different between the two constructed objects?

I know a solution could be:

struct A {
    A() = default;
    int* a1 = nullptr;
    int* a2 = nullptr;
};

Thanks,

Upvotes: 0

Views: 384

Answers (3)

eerorika
eerorika

Reputation: 238461

Why a.a1 is initialized to nullptr

Because you value initialised a. Empty braces are syntax for value initialisation.

while b.a1 is not nullptr?

Because you default initialised b. Lack of any initialiser is syntax for default initialisation.

What is different between the two constructed objects?

One is value initialised and the other is default initialised.

I am facing a crash

The class is trivial(ly default constructible). When a trivial class is default initialised, its members are default initialised as well. A default initialised fundamental object such as a pointer has an indeterminate value. Such value is also commonly called "uninitialised".

Reading an indeterminate value results in undefined behaviour (there are rare exceptions which do not apply to this example). Crash is a possible outcome of undefined behaviour.

A decent compiler will warn you about the bug with a message such as this if you ask to be warned about bugs:

warning: 'b.A::a1' is used uninitialized in this function [-Wuninitialized]

Conclusions: Do not read uninitialised objects. Always initialise or at least assign all objects before first read. Use compiler warnings. Do not ignore compiler warnings. Avoid undefined behaviour.

Upvotes: 1

Aykhan Hagverdili
Aykhan Hagverdili

Reputation: 29985

If you use {}, everything in the class is value-initialized. So, pointers become null-pointer, integers become 0, booleans become false, etc. If you don't, then the fields are default initialized with indeterminate values. Using these values in any way causes undefined behavior.


If you want everything to be deterministically initialized regardless, here is one way to do that:

struct A {
    int* a1 = nullptr;
    int* a2 = nullptr;
};

Here, anything you don't initialize explicitly is initialized for you. But the class is no longer trivially-constructible.

Read more about initialization in cppreference.

Upvotes: 5

User
User

Reputation: 610

It is known as uniform initialization it will initialize all the class variables with default values

    A a{};

You created the object here but you have to manually initialize all the class variables

A b

Upvotes: 0

Related Questions