The correct way to initialize C ++ structures

Our code includes a POD (Plain Old Datastructure) structure (this is a basic C ++ structure that has other POD structures and variables that need to be initialized at the beginning.)

Based on what I read , it seems that:

myStruct = (MyStruct*)calloc(1, sizeof(MyStruct)); 

should initialize all values ​​to zero, as well as:

 myStruct = new MyStruct(); 

However, when the structure is initialized in the second way, Valgrind later complains that "conditional branching or movement depends on uninitialized value (s)" when these variables are used. Is my understanding spoiled here, or is Valgrind throwing false positives?

+66
c ++ initialization struct calloc valgrind
May 6 '11 at 16:39
source share
5 answers

In C ++, classes / structures are identical (in terms of initialization).

A non-POD structure may also have a constructor so that it can initialize members.
If your structure is a POD, you can use an initializer.

 struct C { int x; int y; }; C c = {0}; // Zero initialize POD 

Alternatively, you can use the default constructor.

 C c = C(); // Zero initialize using default constructor C c{}; // Latest versions accept this syntax. C* c = new C(); // Zero initialize a dynamically allocated object. // Note the difference between the above and the initialize version of the constructor. // Note: All above comments apply to POD structures. C c; // members are random C* c = new C; // members are random (more officially undefined). 

I believe Valgrind complains because that is how C ++ worked. (I'm not quite sure when C ++ was updated with a default construct with zero initialization). It is best to add a constructor that initializes the object (constructions are allowed by the constructors).

As a side note:
Many beginners try to evaluate init:

 C c(); // Unfortunately this is not a variable declaration. C c{}; // This syntax was added to overcome this confusion. // The correct way to do this is: C c = C(); 

A quick search for "Most Vexing Parse" will give a better explanation than me.

+96
May 6 '11 at 17:02
source share

From what you told us, this is apparently a false positive in valgrind. The new syntax with () should initialize the object with a value, assuming it is a POD.

Is it possible that some part of your structure is not a POD and that prevents the expected initialization? Can you simplify your code in a mail example that still stands for valgrind error?

Alternatively, your compiler may not actually initialize the POD structure.

In any case, perhaps the easiest solution is to write constructor (s) as needed for struct / subparts.

+2
May 6 '11 at 17:06
source share

You need to initialize all the members that you have in your structure, for example:

 struct MyStruct { private: int someInt_; float someFloat_; public: MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values }; 
+1
May 6 '11 at 16:45
source share

I am writing test code:

 #include <string> #include <iostream> #include <stdio.h> using namespace std; struct sc { int x; string y; int* z; }; int main(int argc, char** argv) { int* r = new int[128]; for(int i = 0; i < 128; i++ ) { r[i] = i+32; } cout << r[100] << endl; delete r; sc* a = new sc; sc* aa = new sc[2]; sc* b = new sc(); sc* ba = new sc[2](); cout << "az:" << a->z << endl; cout << "bz:" << b->z << endl; cout << "a:" << a->x << " y" << a->y << "end" << endl; cout << "b:" << b->x << " y" << b->y << "end" <<endl; cout << "aa:" << aa->x << " y" << aa->y << "end" <<endl; cout << "ba:" << ba->x << " y" << ba->y << "end" <<endl; } 

g ++ compile and run:

 ./a.out 132 az:0x2b0000002a bz:0 a:854191480 yend b:0 yend aa:854190968 yend ba:0 yend 
+1
Jan 21 '17 at 1:25
source share

Since this is a POD structure, you can always set it to 0 - this may be the easiest way to get the fields initialized (assuming it works).

0
May 6 '11 at 16:42
source share



All Articles