C++ 用memset初始化包含数组的结构向量

C++ 用memset初始化包含数组的结构向量,c++,arrays,struct,memset,C++,Arrays,Struct,Memset,我有以下结构 struct a { int array[20] int array2[45] } vector<a> vec; 我已经创建了这个结构的向量 struct a { int array[20] int array2[45] } vector<a> vec; vec; 我用过这个向量机。现在我想初始化(将向量元素中对象内部的所有数组值设置为零)。我该怎么做呢?事实证明,这是一个比第一次出现时有趣得多的问题 tl;

我有以下结构

struct a {
     int array[20]
     int array2[45]
}
vector<a> vec;
我已经创建了这个结构的向量

struct a {
     int array[20]
     int array2[45]
}
vector<a> vec;
vec;

我用过这个向量机。现在我想初始化(将向量元素中对象内部的所有数组值设置为零)。我该怎么做呢?

事实证明,这是一个比第一次出现时有趣得多的问题

tl;dr:如果您使用的是C++03或更高版本的编译器,您不需要费心

你需要理解和之间的区别。基本上,值初始化会将所有元素设置为零,默认初始化会将它们全部保留。如果结构的任何默认元素(递归)具有用户定义的默认构造函数,则值和默认初始化都将调用该构造函数

请注意,值初始化比将
memset
设置为零要好得多,因为

  • 它将调用默认构造函数
  • 它将正确初始化浮点(到0.0)和指针(到NULL)。虽然
    memset
    可能会在您的实现中实现这一点,但它不能保证做到这一点
创建包含n个元素的向量的正常方法是调用:

std::vector<a> vec(n);
技术说明:C++98标准不包含术语“值初始化”,但是
azeroed
的初始化是相同的

C++03

调用了相同的向量构造函数,但是从C++03开始,
value
参数被初始化为value(因此花园中的一切都是美好的)

C++11

电话是

std::vector<a>::vector(size_type count);
std::vector)。如果你这样做,你几乎肯定知道你在做什么

结论

  • 除非您使用的是真正的C++98编译器,否则不需要调用memset
  • 向向量构造函数提供显式值初始化值比调用memset更安全
  • memset可能无法正确初始化非整数内置值(尽管它可能会)
  • memset肯定会击败任何一个合适的构造函数。这是一个巨大的维护风险。如果一个维护程序员改变了结构,使它不再是POD,代码仍然会编译-它只会做错误的事情
  • 只要给结构一个适当的默认构造函数,就有很多话要说,然后你就不必担心是否有任何元素被初始化了,即使你有一个本地副本

阅读评论,有一些代码没有显示,它们填充了向量。现在,您希望重用存储,而不是创建新的存储,并且希望重新初始化它

<> P>任何C++容器的任何算法的典型答案很可能在标准算法中找到。在这种情况下。按照您喜欢的方式初始化您的结构,并将其复制到向量中。按照这些思路:

a A = {0};
std::fill(vec.begin(), vec.end(), A);

如果你想说这还不够快,检查一下。我想你会发现它相当有效。以上代码是绝对安全的,适用于任何正确初始化的
fill
参数。如果不对
a
的实现进行一些假设,我怀疑它是否可以更快

是什么阻止您阅读
std::vector
文档?您为什么决定使用
memset
?得出该结论后,您尝试了什么?@LightnessRacesinOrbit:std::vector通常会为其包含的对象调用默认构造函数。因为这个结构只是内置类型,元素不会被零初始化。@MartinBonner:是的,我知道。OP需要进行一些研究,找出如何将他的元素归零。这个问题没有任何研究成果。我正试图促使OP进行一些研究。你认为他为什么没有?用零初始化对象的副本构造向量,给结构一个默认构造函数,memset都是合理的方法,memset可能是最好的。@MartinBonner
std::vector
将值初始化其元素,而不是默认初始化它们。因此,它们将被初始化为零。您可以通过阅读一些文档来了解这一点。问题是,如果您更改了类型,可能会使结构不再具有POD,这将继续默默地将所有可能是关键bug的内容归零。我发现其中一个曾经在生产中导致了多年的间歇性故障,导致客户损失数千美元。喜欢C++中的类型安全解决方案,尤其是教学时。这不是一个很好的例子。显示的初始化结果是所有元素的初始化数据为零,而不调用
memset
@juanchopanza:Chapter and verse请问?给定结构的定义,默认构造不会初始化它。(或者我弄错了吗?)。[container.requirements.general]将其澄清为
allocator\u traits::construct(m,p)
。从那里,[allocator.traits.members]将其转换为
a.construct(p,std::forward(args)…
(因为这是默认的分配器),[allocator.members]说这是
::new((void*)p)U(std::forward(args)…
,这是args包为空时的值初始化。这有点迂回,可以随分配器而改变,但在几乎所有情况下都应该如此。
a A = {0};
std::fill(vec.begin(), vec.end(), A);