这个问题可能与link重复,但我对这些事情很好奇:
std::fill如果我使用未初始化的原始内存会发生什么坏事?
关于性能,在已经初始化的内存上使用std::uninitialized_fill(当然,具有相同的对象类型)是否更有利/更有害/与使用相同std::fill?
我读了 cppreference 但找不到好的答案
如果我在未初始化的原始内存上使用 std::fill 会发生什么坏事?
如果在调用之前没有在存储中隐式或显式创建适当的对象,那么它将具有未定义的行为。
关于性能,在已初始化的内存(当然,具有相同的对象类型)上使用 std::uninitialized_fill 是否更有利/更有害/与使用 std::fill 相同?
他们不做同样的事情。std::fill进行赋值并std::uninitialized_fill构造新对象。这两种操作的行为可能非常不同,并且其中一种操作不能被另一种操作替代。
std::uninitialized_fill请注意,在 C++20 之前,对于可以按照您建议的方式使用的位置存在限制。也就是说,如果类型包含引用类型或子对象的非静态数据成员,则会导致未定义的行为const。
另外,一般来说,您需要先手动销毁对象,然后再使用std::uninitialized_fill. 否则,如果该类型具有重要的析构函数,那么您至少会面临内存/资源泄漏的风险,并且如果析构函数调用具有将被忽略的重要副作用,则可能会出现未定义的行为。
此外,std::uninitialized_fill如果其中一个构造抛出异常,则将销毁已经构造的对象,这意味着如果操作抛出异常,您最终可能会“丢失”一些对象,在这种情况下,当它尝试销毁原始对象时,它们是原始对象的所有者,将导致未定义的行为。
即使你的类型有微不足道的破坏,如果你处于一种std::fill不起作用但又std::uninitialized_fill起作用的情况,那么你很可能正在尝试做一些你不应该做的事情。
例如,std::uninitialized_fill可以按照您建议的方式使用,以其他方式不能修改对象的方式,因为该类不提供这样做的接口。如果您仍然使用std::uninitialized_fill,则很有可能会破坏拥有这些对象的人的一些假设的不变量。
实际上,很少有使用的理由std::uninitialized_fill。std::uninitialized_fill仅当您在某些字节缓冲区中手动管理对象时才应使用。