【问题标题】:set_union got wrong result when i called it twice当我调用它两次时,set_union 得到了错误的结果
【发布时间】:2019-09-23 19:00:14
【问题描述】:

这个问题让我困惑了好几个小时, 请帮我! 第一次调用set_union,结果是对的,第二次调用,结果不对,看代码:

std::vector<int> set1{ 1, 2, 3, 4, 5, 6 };
std::vector<int> set2{ 4, 5, 6, 7, 8 };
std::vector<int> result{};

std::set_union(std::begin(set1), std::end(set1),
    std::begin(result), std::end(result), 
    std::back_inserter(result));  
// result is 1 2 3 4 5 6

std::back_insert_iterator< std::vector<int>> back2 =
    std::set_union(std::begin(set2), std::end(set2), 
        std::begin(result), std::end(result), 
        std::back_inserter(result)); 

我调试了上面的代码,得到这个结果:

[0] 1   int
[1] 2   int
[2] 3   int
[3] 4   int
[4] 5   int
[5] 6   int
[6] 1   int
[7] - 572662307 int
[8] - 572662307 int
[9] - 572662307 int
[10] - 572662307    int
[11] - 572662307    int
[12]    4   int
[13]    5   int
[14]    6   int
[15]    7   int
[16]    8   int

【问题讨论】:

    标签: c++ algorithm stl set-union


    【解决方案1】:

    结果范围不能与任一输入范围重叠。 https://en.cppreference.com/w/cpp/algorithm/set_union

    你为什么不用这个?

     std::set_union(std::begin(set1), std::end(set1), 
        std::begin(set2), std::end(set2), 
        std::back_inserter(result)); 
    

    【讨论】:

      【解决方案2】:

      你在这里有未定义的行为。当您将迭代器传递给result 作为std::set_union 的输入和输出参数时,写入输出迭代器会使所有输入迭代器无效。这是由于std::vector 的内存布局 - 如果容量不能容纳新元素,写入它可能需要将其所有数据移动到新的内存位置,因此引用初始内存的引用/指针/迭代器无法再使用位置。

      您想将结果存储在新容器中,例如

      std::vector<int> out;
      std::set_union(std::begin(set2), std::end(set2), 
          std::begin(result), std::end(result), 
          std::back_inserter(out));
      

      另请注意,对于第一次调用,std::copy 是更合适的算法(或赋值 result = set1;)。

      【讨论】:

        猜你喜欢
        • 2017-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多