97

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

根据我读过的内容,似乎:

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

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

myStruct = new MyStruct();

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

4

6 回答 6

140

在 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{};          // 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).

我相信 valgrind 在抱怨,因为这就是 C++ 过去的工作方式。(我不确定何时使用零初始化默认构造升级 C++)。最好的办法是添加一个初始化对象的构造函数(结构是允许的构造函数)。

附带说明:
很多初学者都尝试重视 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();

快速搜索“Most Vexing Parse”将提供比我更好的解释。

于 2011-05-06T17:02:29.937 回答
2

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

您的结构的某些子部分是否可能实际上不是 POD 并且这会阻止预期的初始化?您是否能够将代码简化为仍然标记 valgrind 错误的可发布示例?

或者,您的编译器可能实际上并未对 POD 结构进行值初始化。

在任何情况下,最简单的解决方案可能是根据结构/子部分的需要编写构造函数。

于 2011-05-06T17:06:55.733 回答
1

我写了一些测试代码:

#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
于 2017-01-21T01:25:36.760 回答
0

由于它是一个 POD 结构,因此您始终可以将其设置为 0 - 这可能是初始化字段的最简单方法(假设这是适当的)。

于 2011-05-06T16:42:27.140 回答
0

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

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

  public:
    MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values

};
于 2011-05-06T16:45:49.330 回答
0

在我看来,这是最简单的方法。可以使用花括号“{}”初始化结构成员。例如,以下是有效的初始化。

struct Point 
{ 
   int x, y; 
};  

int main() 
{ 
   // A valid initialization. member x gets value 0 and y 
   // gets value 1.  The order of declaration is followed. 
   struct Point p1 = {0, 1};  
}

有关于 c++ 中结构的好信息 - https://www.geeksforgeeks.org/structures-in-cpp/

于 2020-01-26T20:14:20.383 回答