简体   繁体   English

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

[英]using memset to initialize vector of structure which contains array

I have following structure 我有以下结构

struct a {
     int array[20]
     int array2[45]
}

I have created vector of this structure 我已经创建了这种结构的载体

vector<a> vec;

I have used this vec. 我用过这个vec。 Now i Want to initialize(setting all array values inside object in the vector element) to zero. 现在我想初始化(将矢量元素中对象内部的所有数组值设置为零)。 How can i do it.? 我该怎么做。?

Reading the comments, there's code you haven't shown that populated your vector. 阅读注释后,您尚未看到填充您的向量的代码。 Now you'd like to reuse the storage instead of creating a new one, and you want to re-initialize it. 现在,您想重用该存储而不是创建一个新存储,并且想要重新初始化它。

The canonical answer for any algorithm for any C++ container is likely found among the standard algorithms. 在标准算法中很可能找到针对任何C ++容器的任何算法的规范答案。 In this case, std::fill . 在这种情况下, std :: fill Initialize your structure how you like, and copy that to your vector. 初始化您喜欢的结构,然后将其复制到向量中。 Along these lines: 遵循以下原则:

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

If you're tempted to say that's not fast enough, check. 如果您想说那还不够快,请检查一下。 I think you'll find it's quite efficient. 我认为您会发现它非常有效。 The above code is absolutely safe, and works for any correctly initialized argument to fill . 上面的代码是绝对安全的,并且可以对任何正确初始化的参数fill起作用。 I doubt it can be made faster without making some assumptions about the implementation of a . 我怀疑它可以制成没有作出关于实施一些假设更快的a

It turns out that this is a much more interesting question than it first appears. 事实证明,这是一个比最初出现的问题有趣得多的问题。

tl;dr: If you are using a C++03 or later compiler, you don't need to bother. tl; dr:如果使用的是C ++ 03或更高版本的编译器,则无需打扰。

You need to understand the difference between value initialization and default initialization . 您需要了解值初始化默认初始化之间的区别。 Basically value initialization will set all the elements to zero, and default initialization wil leave them all alone. 基本上,值初始化会将所有元素设置为零,而默认初始化将使它们全部保持单独状态。 If any of the default elements of the structure (recursively) have a user defined default constructor, then both value and default initialization will call that. 如果结构的任何默认元素(递归)都具有用户定义的默认构造函数,则value和默认初始化都将调用它。

Note that value initialization is much better than memset to zero because 请注意,将值初始化比将memset设置为零好得多,因为

  • It will call default constructors 它将调用默认构造函数
  • It will correctly initialize floating point (to 0.0) and pointers (to NULL). 它将正确初始化浮点(到0.0)和指针(到NULL)。 Although memset will probably do that on your implementation, it isn't guaranteed to. 尽管memset 可能会在您的实现中执行此操作,但不能保证做到这一点。

The normal way to create a vector with n elements is just to call: 创建具有n个元素的向量的通常方法是调用:

std::vector<a> vec(n);

C++98 C ++ 98

this will call 这会打电话

std::vector<a>::vector(size_type count, 
                       const T& value = T(),
                       const Allocator& alloc = Allocator());

The value object will be default constructed, and you will need to initialize the elements somehow. value对象将是默认构造的,您将需要以某种方式初始化元素。 The best way to do that, is to provide a properly value initialized value to be copied. 最好的方法是提供一个正确的值初始化值以进行复制。 So: 所以:

const static a azeroed;  // Because this is static, it will be value initialized
std::vector<a> vec(20,azeroed);

Technical note: The C++98 standard doesn't contain the term "value initialization", but the initialization of azeroed is identical. 技术说明:C ++ 98标准不包含“值初始化”一词,但是azeroed的初始化是相同的。

C++03 C ++ 03

The same vector constructor is called, but from C++03, the value argument is value initialized (so everything in the garden is rosy). 调用了相同的向量构造函数,但是从C ++ 03开始, value参数值初始化的(因此,花园中的所有东西都是玫瑰色的)。

C++11 C ++ 11

The call is to 电话是

std::vector<a>::vector(size_type count);

which value initializes the elements directly. 该值直接初始化元素。

C++14 C ++ 14

The call is to 电话是

std::vector<a>::vector(size_type count, const Allocator& alloc = Allocator());

(basically, they realized they forgot the allocator argument). (基本上,他们意识到他们忘记了分配器参数)。 There is a very subtle difference here, in that the elements are constructed by calls to Allocator::construct , and although the default allocator will value initialize the elements, it is possible to provide a custom version which doesn't (see this answer ). 这里有一个非常细微的区别,因为元素是通过对Allocator::construct construct的调用来Allocator::construct ,尽管默认分配器将对元素进行初始化,但是可以提供一个不包含该元素的自定义版本(请参见此答案 ) 。 If you are doing that, you almost certainly know what you are doing. 如果这样做,几乎可以肯定您知道自己在做什么。

Conclusion 结论

  • Unless you are using a real C++98 compiler, you don't need to call memset 除非您使用的是真正的C ++ 98编译器,否则无需调用memset
  • Providing an explicitly value initialized value to the vector constructor is safer than calling memset. 向向量构造函数提供显式值初始化的值比调用memset更安全。
  • memset may not properly initialize non-integral built-in values (although it probably will). memset可能无法正确初始化非整数内置值(尽管可能会正确)。
  • memset will definitely clobber anything will a proper constructor. memset 肯定会破坏任何适当的构造函数。 This is a huge maintenance hazard. 这是巨大的维护危险。 If a maintenance programmer changes the structure so it is no longer POD, the code will still compile - it will just do the wrong thing. 如果维护程序员更改了结构,使其不再是POD,则代码仍将编译 -这只会做错事。
  • There is a lot to be said for just giving the struct a proper default constructor, and then you never have to worry about whether any of the elements are initialized, even if you have a local copy. 只是给struct一个适当的默认构造函数,要说很多话,那么即使您有本地副本,也不必担心是否初始化了任何元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM