正确的方法来初始化C ++结构

我们的代码包含一个POD(普通的旧数据结构)结构(它是一个基本的C ++结构,它有其他结构和PODvariables,需要在开始时进行初始化)。

根据我所阅读的内容 ,似乎是:

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

应将所有值初始化为零,如下所示:

 myStruct = new MyStruct(); 

但是,当结构以第二种方式初始化时,Valgrind稍后会在使用这些variables时抱怨“条件跳转或移动取决于未初始化的值”。 我的理解是有缺陷的,还是Valgrind误报?

在C ++类/结构是相同的(在初始化方面)。

一个非POD结构可能有一个构造函数,所以它可以初始化成员。
如果你的结构是一个POD,那么你可以使用一个初始化器。

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

或者,您可以使用默认的构造函数。

 C c = C(); // Zero initialize using default constructor 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). 

我相信valgrind抱怨,因为这是C ++如何工作。 (我不是很确定C ++是否在零初始化的默认构造下升级)。 你最好的select是添加一个构造函数来初始化对象(结构是允许的构造函数)。

作为一个方面说明:
很多初学者试图评估init:

 C c(); // Unfortunately this is not a variable declaration. // The correct way to do this is: C c = C(); 

快速search“最烦人的parsing”将提供比我更好的解释。

从你所告诉我们的情况来看,这似乎是Valgrind的误判。 ()new语法应该初始化对象,假设它是POD。

是否有可能,你的结构的一些子部分实际上不是POD,这阻止了预期的初始化? 你能够简化你的代码到一个仍然标志着valgrind错误的postable例子吗?

另外也许你的编译器实际上并不初始化POD结构。

在任何情况下,最简单的解决scheme是根据struct / subparts的需要编写构造函数。

您需要初始化您在结构中的任何成员,例如:

 struct MyStruct { private: int someInt_; float someFloat_; public: MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values }; 

我写了一些testing代码:

 #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 ++编译并运行:

 ./a.out 132 az:0x2b0000002a bz:0 a:854191480 yend b:0 yend aa:854190968 yend ba:0 yend 

由于它是一个POD结构,所以你可以将它memset到0,这可能是获得字段初始化的最简单的方法(假设这是合适的)。