El problema es que su c
está vacío porque se inicializó sin elementos, sin mencionar la llamada innecesaria al clear()
. std::merge()
toma un iterador de salida como su último argumento. Si c.begin()
se refiere al comienzo de std::vector
que ya contiene elementos suficientes, entonces esto no es un problema, esos elementos simplemente se sobrescribirán. Tal como está, está invocando un comportamiento indefinido escribiendo valores en la memoria pasado al final del vector.
Para garantizar que c
tiene espacio suficiente para los elementos, se puede hacer esto:
c.resize(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), c.begin());
Sin embargo, es más idiomático utilizar un std::back_insert_iterator
, un iterador de salida que llama push_back()
. Para una mejor eficacia, puede llamar al reserve()
en el vector de antemano. Esto asegura que c
solo necesita asignar memoria una vez, en lugar de crecer durante la llamada al std::merge()
. La solución final se parece a esto:
#include <iterator>
// ...
c.reserve(a.size() + b.size());
std::merge(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(c));
Su respuesta es correcta, pero no utilizaría el término 'reserva ', ya que significa algo completamente diferente de' resize'. –
¿Por qué eligió llamar a la segunda solución "mejor"? Yo diría lo contrario, ya que se conoce el tamaño y la primera variante es ciertamente más eficiente y no realmente más compleja que la segunda. –
@KonradRudolph: el segundo es menos propenso a errores, y más general, puede conocer el tamaño en este caso, pero a veces no. – Fanael