Reputation: 21
I used to know that uninitialized member variables are initialized with a garbage value.
But, If there is a pointer variable uninitialized in a class, all of the uninitialized member variables are initialized with zero.
I think the pointer variable is just pointing an instance in heap memory.
Why are other variables changed?
I don't know what the difference is between these initializations.
Below is the code I tried for step by step.
#include <iostream>
using namespace std;
class Test {
private:
int val1;
int val2;
public:
void PrintValue() {
cout << "val1: " << val1 << endl;
cout << "val2: " << val1 << endl;
}
};
int main() {
Test a;
a.PrintValue();
}
then, the result is
val1: -858993460
val2: -858993460
In this code, I added 'int* ptr = new int' like below.
#include <iostream>
using namespace std;
class Test {
private:
int val1;
int val2;
int* ptr = new int;
public:
void PrintValue() {
cout << "val1: " << val1 << endl;
cout << "val2: " << val1 << endl;
}
};
int main() {
Test a;
a.PrintValue();
}
The result is like this.
val1: 0
val2: 0
Why does this happen?
I'm using VS community 2019 and build tools v142.
Upvotes: 2
Views: 91
Reputation: 2946
The difference here is that adding the int* ptr = new int
changes your class under the hood from a POD
(plain old data) class to a non-POD
class.
If you try with your first example
class Test {
public:
int val1;
int val2;
void PrintValue() {
cout << "val1: " << val1 << endl;
cout << "val2: " << val1 << endl;
}
};
int main() {
Test t;
cout << t.val1 << endl;
}
Then you will get a compiler error because it knows you are trying to access uninitialized variables.
However, when you add the more complex int* ptr = new int
then your class becomes non-POD and so the compiler creates a default constructor for you, which will initialize your variables for you.
Therefore
class Test {
public:
int val1;
int val2;
int* ptr = new int;
void PrintValue() {
cout << "val1: " << val1 << endl;
cout << "val2: " << val1 << endl;
}
};
int main() {
Test t;
cout << t.val1 << endl;
}
This becomes legal and will now compile (although as other answers pointed out, while the output of this may look cleaner, and it won't throw an error, accessing these default initialed variables may still be UB)
Upvotes: 1
Reputation: 172884
Nothing changed. As the effect of default initialization, the data member val1
and val2
will be initialized to indeterminate value; any use of them leads to UB, anything is possible.
otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.
Default initialization of non-class variables with automatic and dynamic storage duration produces objects with indeterminate values
Upvotes: 5