以下代码以核心转储结束。 我做错了什么?
std::vector<int> a;
a.push_back(1);
a.push_back(4);
a.push_back(7);
std::vector<int> b;
b.push_back(2);
b.push_back(5);
b.push_back(8);
std::vector<int> c;
c.clear();
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
for (it=c.begin(); it!=c.end(); ++it)
std::cout << *it << endl;
我可以使用stl或boost中的其他合并函数吗?
谢谢!
答案 0 :(得分:9)
问题是你的c
是空的,因为它是在没有元素的情况下初始化的,更不用说对clear()
的不必要的调用了。 std::merge()
将输出迭代器作为其最后一个参数。如果c.begin()
指的是已经包含足够元素的std::vector
的开头,那么这不是问题 - 这些元素只会被覆盖。实际上,您通过将值写入内存过去向量的末尾来调用未定义的行为。
为确保c
有足够的空间容纳元素,您可以这样做:
c.resize(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
但是,使用调用std::back_insert_iterator
的输出迭代器push_back()
更为惯用。为了提高效率,您可以事先在向量上调用reserve()
。这确保c
只需要分配一次内存,而不是在调用std::merge()
期间增长。最终解决方案如下所示:
#include <iterator>
// ...
c.reserve(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
答案 1 :(得分:2)
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
^^^^^^^^^^^^^^^^^^^^^^^
问题是如果你传递c.begin()
,合并函数将开始将值写入*c.begin()
,*(c.begin() + 1)
等,这会导致未定义的行为,包括核心转储。你有两个选择。
c
足够大,以容纳合并将要写入的所有值。例如,您可以在致电c.resize(a.size()+b.size());
merge
std::back_insert_iterator
。它的例子在我的答案的开头给出。每次*it = x
it
为back_insert_iterator
时,它都会push_back
x进入基础容器。可以找到有关后插入迭代器的信息here。 back_inserter
只是一个便利功能,因此您不会编写很多模板参数。
答案 2 :(得分:2)
您试图将结果存储在c
中,这是空的,因此,它没有足够的空间来存储它们(实际上,它没有足够的空间来存储任何)。尝试使用back_insert_iterator
代替push_back
元素:
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
答案 3 :(得分:1)
c
不足以保持合并。尝试:
#include <iterator>
...
std::merge(a.begin(), a.end(),
b.begin(), b.end(),
std::back_inserter(c));