简体   繁体   中英

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. 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. In this case, 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 . I doubt it can be made faster without making some assumptions about the implementation of 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.

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.

Note that value initialization is much better than memset to zero because

  • It will call default constructors
  • It will correctly initialize floating point (to 0.0) and pointers (to NULL). Although memset will probably do that on your implementation, it isn't guaranteed to.

The normal way to create a vector with n elements is just to call:

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

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. 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++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++11

The call is to

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

which value initializes the elements directly.

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 ). 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
  • Providing an explicitly value initialized value to the vector constructor is safer than calling memset.
  • memset may not properly initialize non-integral built-in values (although it probably will).
  • memset will definitely clobber anything will a proper constructor. 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.
  • 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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