Блог пользователя Assyll

Автор Assyll, история, 3 года назад, По-русски

Всем привет участники CodeForces! У меня тут вопрос по поводу итераторов. В недавном турнире Codeforces Round #696 (Div. 2) в задаче С разбирая решебник я столкнулся с проблемой Segmentation fault: 11 в функции check.

Решение задачи автора

Я переделал код чут подсебя:

vector<int> check(int a[], int n, int x) {
    multiset<int> s;

    for(int i=0; i < 2*n; ++i){
        s.insert(a[i]);
    }

    vector<int> ans;

    for(int i=0; i < n; ++i){
        auto max_pos = s.end(); //выбираем максимальный элемент
        max_pos--;

        int b = x - *max_pos;
        s.erase(max_pos); // удаляем максимальный элемент

        if(s.find(b) == s.end()){
            return {};
        }

        x = max(*max_pos, b);
        
        ans.push_back(*max_pos);
        ans.push_back(b);

        s.erase(s.find(b));
    }
    return ans;
}

Тут вопрос, почему если я опускаю строку где комментария "// удаляем максимальный элемент" ниже if то дает Segmentation fault: 11, erase тут же ассоциативное? IgorI можете тоже посмотреть? Спасибо!

  • Проголосовать: нравится
  • +3
  • Проголосовать: не нравится

»
3 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Получаешь SIGSEGV потому, что разыменовываешь невалидный (после erase) итератор в строчке x = max(*max_pos, b);.

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    То есть указатель итератора меняется?

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится +18 Проголосовать: не нравится

      Когда ты делаешь erase -- все, элемента больше нет в памяти, не к чему больше обращаться. Поэтому при разыменовании может получиться 0, -1, случайное число, или assertion failed, или segmentation fault, или bus error, или будет TLE. Это Undefined Behavior.