the following code ends up with a core dump. What do I do wrong?
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;
Is there any other merging function in the stl or in boost that I could be using?
Thanks!
The problem is that your c is empty because it was initialised with no elements, not to mention the unnecessary call to clear(). std::merge() takes an output iterator as its last argument. If c.begin() refers to the beginning of a std::vector that already contains enough elements, then this isn’t a problem—those elements will just be overwritten. As it is, you’re invoking undefined behaviour by writing values into memory past the end of the vector.
To ensure that c has enough space for the elements, you could do this:
c.resize(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
However, it is more idiomatic to use a std::back_insert_iterator, an output iterator that calls push_back(). For better efficiency, you can call reserve() on the vector beforehand. This ensures that c only needs to allocate memory once, rather than as it grows during the call to std::merge(). The final solution looks like this:
#include <iterator>
// ...
c.reserve(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With