正确的方法来初始化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,这可能是获得字段初始化的最简单的方法(假设这是合适的)。