【问题标题】:Vector element duplication when capacity is reached达到容量时的向量元素重复
【发布时间】:2021-05-16 15:35:27
【问题描述】:

在程序中如下:

#include <vector>
#include <memory>
#include <iostream>

int main()
{
    std::vector<std::shared_ptr<int>> v{ std::make_shared<int>() };

    for ( auto i = v.capacity() - v.size() + 1; i-- > 0; )
        v.push_back( v.back() );

    for ( auto i = v.capacity() - v.size() + 1; i-- > 0; )
        v.insert( v.end(), --v.end(), v.end() );

    for ( const auto & p : v )
    {
        std::cout << ( p ? "valid_ptr" : "null" ) << std::endl;
    }
    return 0;
}

一些编译器输出(Visual Studio、ellcc):

valid_ptr
valid_ptr
valid_ptr

而其他(gcc、clang、icc)输出:

valid_ptr
valid_ptr
null

假设使用push_back 复制最后一个元素总是正确工作,即使当向量达到其容量并需要重新分配时,这是否正确?

同时使用insert 复制最后一个元素是未定义的或特定于实现的行为?

【问题讨论】:

  • 不是insert 是显示代码中未定义的行为。这是push_back
  • 为什么不分别运行push_back()insert()

标签: c++ vector stl undefined-behavior


【解决方案1】:

v.insert( v.end(), --v.end(), v.end() ) 表现出未定义的行为,违反了标准库函数的先决条件。 [sequence.reqmts]/4 中的表 87 表示:

a.insert(p,i,j)
要求: ij 不是 a 的迭代器。


v.push_back( v.back() ); 保证可以工作,我相信。请参阅DR#526 说“vector::insert(iter, value) 需要工作,因为标准不允许它不工作。” push_back 应该出于同样的原因工作。

DR#2164 中讨论了更广泛的问题类别,其中emplace 可以采用任意数量的参数,其中一些可能引用容器的元素和/或其子对象。共识似乎是应该需要实施才能使其发挥作用。

【讨论】:

    猜你喜欢
    • 2014-11-21
    • 2018-09-30
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多