Я пытаюсь объединить несколько векторов, чтобы создать результирующий вектор, который является объединением элементов во входных векторах, используя STL в C ++. Каждый вход уже в отсортированном порядке, а элементы без знака коротки.
Я получаю сообщение об ошибке «Выражение: векторный итератор + смещение вне диапазона», и я не могу сказать, почему. Это отладочная сборка, выполняемая в отладчике Visual Studio 2013.
Вот код:
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
}
Намерение состоит в том, что вектор длин волн от каждого сканирования (sc) будет объединен с вектором wl. (Вектор wl затем копируется в массив C ++ без знака с помощью кода, не показанного здесь).
temp
имеет нулевой размер, поэтому set_union
пишет мимо его конца. Изменить это на
set_union(wl.begin(), wl.end(), sc.begin(), sc.end(), std::back_inserter(temp));
wl = temp;
temp.clear();
Обновить: Почему векторный темп не увеличивается в размерах автоматически?
Представить temp
пуст и выполняется следующий код:
std::vector<unsigned short>::iterator it = temp.begin();
*it = 123; // Undefined behavior
++it; // UB
*it = 456; // UB
Это именно то, что std::set_union
делается. Он просто записывает в выходной итератор, который вы предоставляете, и увеличивает его. Но обычный векторный итератор не добавляет элементы, вы должны добавить элементы с push_back
, Это то что back_inserter
делает, и именно поэтому это необходимо здесь.