以下代码以核心转储结束。我做错了什么?
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中有没有我可以使用的其他合并函数?
谢谢!
发布于 2012-02-03 00:00:57
问题是您的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());但是,使用调用push_back()的输出迭代器std::back_insert_iterator更为惯用。为了获得更好的效率,您可以预先在向量上调用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));发布于 2012-02-03 00:00:56
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
^^^^^^^^^^^^^^^^^^^^^^^问题是,如果您传递c.begin(),合并函数将开始将值写入*c.begin()、*(c.begin() + 1)等,这将导致未定义的行为,包括核心转储。这里有两个选项。
c足够大,可以容纳merge将要写入的所有值。例如,您可以在调用mergestd::back_insert_iterator之前调用c.resize(a.size()+b.size());。它的例子在我的答案的开头给出了。每次在it是back_insert_iterator的情况下执行*it = x时,它都会将x push_back到底层容器中。有关back insert迭代器的信息可以在here中找到。back_inserter只是一个方便的函数,所以您不需要编写太多的模板参数。
发布于 2012-02-03 00:01:15
您正在尝试将结果存储在c中,因为它是空的,因此没有足够的空间来存储所有结果(实际上,它没有足够的空间来存储任何内容)。尝试使用back_insert_iterator,它将push_back元素:
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));https://stackoverflow.com/questions/9115454
复制相似问题