gpt4 book ai didi

c++ - 为什么即使没有内存重新分配,在 for 循环中调用 push_back 也是不安全的?

转载 作者:太空狗 更新时间:2023-10-29 23:29:44 24 4
gpt4 key购买 nike

当我阅读这篇文章时:https://stackoverflow.com/a/42448319/3336423

我明白,在 for 循环中调用 push_back 是不安全的,因为:

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

那么,我假设如果我保证不会超出容量,那么它就是安全的....

但显然不是,下面的所有实现都会在第一次调用 push_back 后崩溃(使用 Visual Studio),即使我可以看到容量在循环内保持不变(所以我假设 vector 不会重新分配其内存):

版本 1:

std::vector<int> v1{ 3, 4, 5 };
v1.reserve( v1.size()*2 );
size_t c1 = v1.capacity();
for ( auto val : v1 )
{
v1.push_back( val );
c1 = v1.capacity();
}

版本 2:

std::vector<int> v2{ 3, 4, 5 };
v2.reserve( v2.size()*2 );
size_t c2 = v2.capacity();
auto curEnd = v2.end();
for ( auto iter = v2.begin(); iter != curEnd; ++iter )
{
v2.push_back( *iter );
c2 = v2.capacity();
}

版本 3:

std::vector<int> v3{ 3, 4, 5 };
v3.reserve( v3.size()*2 );
size_t c3 = v3.capacity();
for ( auto iter = v3.begin(); iter != v3.end(); ++iter )
{
v3.push_back( *iter );
c3 = v3.capacity();
}

是什么导致这些代码崩溃?

最佳答案

你的前两个版本都有同样的问题。缓存的尾后迭代器在第一次插入后失效,使任何后续使用成为 UB。是的,甚至只是与之比较。

您的第三个示例崩溃了,因为它最终尝试重新插入新插入的元素。所以它最终需要重新分配,最终导致更多的 UB。

正确的基于迭代器的方法是直到最后一个结束。但直到最后,假设 vector 不为空。

std::vector<int> v{ 3, 4, 5 };
v.reserve( v.size()*2 );

auto it = v.begin(), end = v.end();
--end;
do {
v.push_back(*it);
} while (it++ != end); // Check against current position, but increment still

关于c++ - 为什么即使没有内存重新分配,在 for 循环中调用 push_back 也是不安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48518970/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com