Удаление строк в массиве с помощью цикла foreach - PullRequest
0 голосов
/ 10 июля 2020

Я зацикливаю свой массив, чтобы связать одни данные с другими. Если данных нет, я удаляю строку. В основном, если array1[i].frame != array2[i].frame (массивы содержат структуру). Я сделал это:

struct Sarray1 {int frame; /*...*/; Sarray2 sarray2};
struct Sarray2 {int frame; /*...*/;};

std::vector array1<Sarray1>;
std::vector array2<Sarray2>;

        int i = 0;
        for (auto& e : array1)
        {
            if (i >= array2.size())
                break;
            if (e.frame == array2[i].frame) 
                e.sarray2= array2[i];
            else
                array1.erase(array1.begin() + i);
            i++;
        }

Можно ли так делать для удаления данных? Я всегда читаю, что удалять во время al oop нехорошо. Будет ли у меня какой-нибудь странный компортмент? Я не знаю об устойчивости foreach l oop в C ++ при изменении размера.

Заранее спасибо.

1 Ответ

0 голосов
/ 10 июля 2020

Вы используете диапазон l oop, который повторяет каждый элемент. Если вы стираете элемент во время цикла, внутренний итератор становится недействительным. Использование недействительного итератора - это плохо и приводит к неопределенному поведению.

Если вы хотите стереть во время цикла, избегайте использования диапазона на основе l oop. Вместо этого используйте итератор и установите для итератора возвращаемое значение std :: vector :: erase () , который является итератором после последнего удаленного элемента, например:

auto it = array1.begin();
auto it2 = array2.begin();

for (; it != array1.end() && it2 != array2.end(); ++it2)
{
    if (it->frame == it2->frame)
    {
        it->sarray2= it2->array2;
        ++it;
    }
    else
    {
        it = array1.erase(it);
    }
}
...