0

I am attempting to merge several vectors to create a resulting vector that is the union of the elements in the input vectors, using STL in C++. Each input is already in sorted order, and the elements are unsigned short.

I am getting an error "Expression: vector iterator + offset out of range", and I cannot tell why. This is a debug build, running in the Visual Studio 2013 debugger.

Here is the code:

std::vector <unsigned short> wl, temp;
int iS; std::vector <unsigned short>::iterator oi, it;
for (iS=0; iS<nScans; iS++)
{
    std::vector<unsigned short> sc(scan[iS].wavelength, scan[iS].wavelength + scan[iS].nWavelengths);
    oi=set_union(wl.begin(), wl.end(), sc.begin(), sc.end(), temp.begin());
    wl.assign(temp.begin(), oi); // temp is needed because destination cannot overlap source
}

The intent is that a vector of wavelengths from each scan (sc) will be merged into the vector wl. (The vector wl is then copied into a C++ array of unsigned short by code not shown here).

Woody20
  • 791
  • 11
  • 30

1 Answers1

4

temp has size zero, so set_union writes past its end. Change that to

set_union(wl.begin(), wl.end(), sc.begin(), sc.end(), std::back_inserter(temp));
wl = temp;
temp.clear();

Demo

Update: Why the vector temp doesn't increase in size automatically?
Imagine temp is empty and the following code is executed:

std::vector<unsigned short>::iterator it = temp.begin();
*it = 123; // Undefined behavior
++it;      // UB
*it = 456; // UB

That's exactly what std::set_union is doing. It just writes to the output iterator you provide and increments it. But the usual vector iterator doesn't add items, you have to add items with push_back. That's what back_inserter is doing, and that's why it is needed here.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • I think I understand your suggestion, but can you explain why the vector temp doesn't increase in size automatically? I thought that was the purpose of the vector container: to expand as needed. – Woody20 Sep 25 '14 at 16:21
  • @Woody20 I've tried to explain, see my updated answer. – Anton Savin Sep 25 '14 at 18:33