初始化 C++ 结构的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5914422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Proper way to initialize C++ structs
提问by Shadow503
Our code involves a POD (Plain Old Datastructure) struct (it is a basic c++ struct that has other structs and POD variables in it that needs to get initialized in the beginning.)
我们的代码涉及一个 POD(Plain Old Datastructure)结构(它是一个基本的 c++ 结构,其中包含其他结构和 POD 变量,需要在开始时进行初始化。)
Based one what I've read, it seems that:
根据我读过的内容,似乎:
myStruct = (MyStruct*)calloc(1, sizeof(MyStruct));
should initialize all the values to zero, as does:
应该将所有值初始化为零,如下所示:
myStruct = new MyStruct();
However, when the struct is initialized in the second way, Valgrind later complains "conditional jump or move depends on uninitialised value(s)" when those variables are used. Is my understanding flawed here, or is Valgrind throwing false positives?
但是,当以第二种方式初始化结构体时,Valgrind 稍后会在使用这些变量时抱怨“条件跳转或移动取决于未初始化的值”。我的理解在这里有缺陷,还是 Valgrind 抛出误报?
回答by Martin York
In C++ classes/structs are identical (in terms of initialization).
在 C++ 中,类/结构是相同的(就初始化而言)。
A non POD struct may as well have a constructor so it can initialize members.
If your struct is a POD then you can use an initializer.
非 POD 结构也可以有一个构造函数,以便它可以初始化成员。
如果您的结构是 POD,那么您可以使用初始化程序。
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 is complaining because that is how C++ used to work. (I am not exactly sure when C++ was upgraded with the zero initialization default construction). Your best bet is to add a constructor that initializes the object (structs are allowed constructors).
我相信 valgrind 正在抱怨,因为这就是 C++ 过去的工作方式。(我不确定何时使用零初始化默认构造升级 C++)。最好的办法是添加一个初始化对象的构造函数(结构体是允许的构造函数)。
As a side note:
A lot of beginners try to value init:
附带说明:
很多初学者都试图重视 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 the "Most Vexing Parse" will provide a better explanation than I can.
快速搜索“Most Vexing Parse”将提供比我更好的解释。
回答by Mark B
From what you've told us it does appear to be a false positive in valgrind. The new
syntax with ()
should value-initialize the object, assuming it is POD.
从你告诉我们的情况来看,它在 valgrind 中似乎是一个误报。的new
语法()
应值初始化对象,假设它是POD。
Is it possible that some subpart of your struct isn't actually POD and that's preventing the expected initialization? Are you able to simplify your code into a postable example that still flags the valgrind error?
您的结构的某些子部分是否可能实际上不是 POD 并且阻止了预期的初始化?您是否能够将您的代码简化为仍然标记 valgrind 错误的可发布示例?
Alternately perhaps your compiler doesn't actually value-initialize POD structures.
或者,您的编译器实际上并未对 POD 结构进行值初始化。
In any case probably the simplest solution is to write constructor(s) as needed for the struct/subparts.
在任何情况下,最简单的解决方案可能是根据结构/子部分的需要编写构造函数。
回答by Yadong
I write some 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:
g++ 编译并运行:
./a.out
132
az:0x2b0000002a
bz:0
a:854191480 yend
b:0 yend
aa:854190968 yend
ba:0 yend
回答by Michael Klishevich
That seems to me the easiest way. Structure members can be initialized using curly braces ‘{}'. For example, following is a valid initialization.
这在我看来是最简单的方法。可以使用花括号“{}”初始化结构成员。例如,以下是有效的初始化。
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};
}
There is good information about structs in c++ - https://www.geeksforgeeks.org/structures-in-cpp/
有关于 c++ 中结构的好信息 - https://www.geeksforgeeks.org/structures-in-cpp/
回答by Scott C Wilson
Since it's a POD struct, you could always memset it to 0 - this might be the easiest way to get the fields initialized (assuming that is appropriate).
由于它是一个 POD 结构,你总是可以将它设置为 0 - 这可能是初始化字段的最简单方法(假设这是合适的)。
回答by ralphtheninja
You need to initialize whatever members you have in your struct, e.g.:
您需要初始化结构中的任何成员,例如:
struct MyStruct {
private:
int someInt_;
float someFloat_;
public:
MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values
};