2

Inspired by this question I wrote my own little program (using code from this answer) and discovered things that confused me. Namely:

Having those classes:

class A {
  public:
    A(){}
    int i;
    int j;
};

class B {
  public:
    B() = default;
    int i;
    int j;
};

I wrote 4 usages of those classes with different object construction usages:

//1
A* pa = new A(); // followed by delete pa
B* pb = new B(); // followed by delete pb
//2
shared_ptr<A> pa = make_shared<A>();
shared_ptr<B> pb = make_shared<B>();
//3
shared_ptr<A> pa ( new A() );
shared_ptr<B> pb ( new B() );
//4
shared_ptr<A> pa ( new A );
shared_ptr<B> pb ( new B );

and after this I have used them to print their values like so:

for( int i = 0; i < 3; ++i)
{
  ...1..2..3..4
  cout << "A : " << pa->i << "," << pa->j << endl;
  cout << "B : " << pb->i << "," << pb->j << endl;
}

What I have received on the output surprised me:

//1
A : 0,0
B : 0,0
A : 7388176,0
B : 0,0
A : 7388208,0
B : 0,0

//2
A : 0,0
B : 0,0
A : 0,0
B : 0,0
A : 0,0
B : 0,0

//3
A : 0,0
B : 0,0
A : 25848848,0
B : 0,0
A : 25848880,0
B : 0,0

//4
A : 0,0
B : 0,0
A : 39619600,0
B : 39619664,0
A : 39619632,0
B : 39619696,0

While the first one is described in aforementioned question's answers what is happening in //2, //3, //4?

I used gcc 4.9.2 and 5.1.0 on Ubuntu 64 bit with the same results.

Ideone link

Community
  • 1
  • 1
Patryk
  • 22,602
  • 44
  • 128
  • 244

2 Answers2

5

Your first three code snippets value-initialize the objects constructed.

If the class's default constructor is not user-provided, value-initialization performs zero-initialization, and then call the default constructor; otherwise, it just calls the default constructor.

Now apply the discussion in the question linked.

For the make_shared case where you see all zeroes in both cases, that's just one possible manifestation of undefined behavior. Nothing more.


The final snippet default-initializes the objects constructed, which, for object of class type, means calling the default constructor, which in each case performs no initialization.

T.C.
  • 133,968
  • 17
  • 288
  • 421
0

You never initialize i and j. The behaviour is undefined then - random.

Stefan
  • 1,131
  • 2
  • 12
  • 30
  • It is defined when using default constructor (not user defined) as mentioned in [this answer](http://stackoverflow.com/a/23698999/675100) (based on standard) – Patryk May 11 '15 at 22:51