使用 std::uninitialized_copy 到已初始化的内存

Jeo*_*Kim 4 c++ copy language-lawyer

如果std::uninitialized_copy用于初始化的内存,这种使用是否会导致内存泄漏或未定义的行为?

例如:

std::vector<std::string> u = {"1", "2", "3"};
std::vector<std::string> v = {"4", "5", "6"};
// What happens to the original elements in v?
std::uninitialized_copy(u.begin(), u.end(), v.begin());
Run Code Online (Sandbox Code Playgroud)

Hol*_*Cat 7

TL;DR:不要这样做。

\n

假设您的std::string实现使用 SSO 1(我相信所有现代的实现都使用 SSO 1),那么只有当字符串足够短以进行 SSO 时,才不会泄漏任何内容。

\n

这里任何可能的 UB 均受以下管辖[basic.life]/5

\n
\n

程序可以通过重用或释放如上所述的存储来结束类类型的对象的生命周期而不调用析构函数。

\n

[注 3:删除表达式 ([expr.delete]) 在释放存储之前调用析构函数。\n\xe2\x80\x94 尾注]

\n

在这种情况下,不会隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序都具有未定义的行为。

\n
\n

我不太清楚“依赖副作用”意味着什么(你能郑重声明你不介意没有副作用,并通过这种方式摆脱UB吗?),但是破坏一个SSO\ 'ed 字符串应该没有副作用。

\n

但!如果启用迭代器调试,则无论 SSO 如何,析构函数都可能会产生副作用(以某种方式通知迭代器它们应该失效)。那么跳过析构函数可能会出现问题。

\n
\n

1 SSO = 小(或短)字符串优化 = 不在堆上分配短字符串,而是将其直接嵌入到实例中std::string

\n