简体   繁体   中英

C++ std::fill vs std::uninitialized_fill

This question may be a duplicate of link , but I'm curious of these things:

  1. What bad thing will happen if I use std::fill on uninitialized raw memory?

  2. Regarding performance, is using std::uninitialized_fill on already initialized memory (of course, with the same object type) more beneficial/more harmful/just the same as using std::fill ?

I read cppreference but can't find good answer

What bad thing will happen if I use std::fill on uninitialized raw memory?

If appropriate objects have not been implicitly or explicitly created in the storage prior to the call, then it will have undefined behavior.

Regarding performance, is using std::uninitialized_fill on already initialized memory (of course, with the same object type) more beneficial/more harmful/just the same as using std::fill?

They don't do the same thing. std::fill does assignment and std::uninitialized_fill constructs new objects. These two operations could potentially behave very differently and one is not replaceable by the other.

Note that prior to C++20 there were restrictions on where std::uninitialized_fill could be used in the way you suggest. Namely it would result in undefined behavior if the type contained a non-static data member of reference type or a const subobject.

Also, in general, you would need to manually destroy the objects first before placing new ones with std::uninitialized_fill . Otherwise you are at least risking memory/resource leaks if the type has a non-trivial destructor, and potentially undefined behavior if the destructor call has important side effects that would be omitted.

Furthermore, std::uninitialized_fill will destroy already constructed objects if one of the constructions throws an exception, which means that you might end up with some objects "missing" if the operation throws, in which case the owner of the original objects, when it tries to destroy them, will cause undefined behavior.

Even if your type has trivial destruction, if you are in a situation where std::fill doesn't work, but std::uninitialized_fill does, then there is a good chance that you are trying to do something that you are not supposed to do.

For example std::uninitialized_fill can be used in the way you suggest to modify objects in ways that you could otherwise not because the class doesn't provide an interface to do so. If you use std::uninitialized_fill nonetheless, there is a good chance that you are breaking some assumed invariant of whoever owns these objects.

Practically speaking there is rarely a reason to use std::uninitialized_fill . std::uninitialized_fill should be used only if you are managing objects manually in some byte buffer.

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