Разница в удалении элемента из вектора и вектора пар - PullRequest
0 голосов
/ 04 июля 2018
#include <bits/stdc++.h>
using namespace std;

int main() 
{
    vector<int>p;
    p.push_back(30);
    p.push_back(60);
    p.push_back(20);

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i]<<" ";
}

Приведенный выше код выдает ошибку, поскольку понятно, что p.end () указывает на нулевой указатель.

Пока этот код работает нормально и выводится 30 60. Кто-нибудь может это объяснить?

#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
int main() 
{
    vector<pair<int,int>>p;
    p.push_back(mp(30,2));
    p.push_back(mp(60,5));
    p.push_back(mp(20,7));

    p.erase(p.end());

    for(int i = 0; i < p.size(); ++i)
    cout<<p[i].first<<" ";
}

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Приведенный выше код выдает ошибку, поскольку понятно, что ...

Этот код не гарантирует "выбросить ошибку". Скорее, поведение не определено. Бросок ошибки - одно из возможных действий. Если он выдаст ошибку, вы можете считать себя счастливчиком, так как в противном случае было бы трудно найти вашу ошибку.

... так как понятно, что p.end () указывает на нулевой указатель.

Нет, p.end() не "указывает на нулевой указатель". Он указывает на конец вектора, где конец вектора определяется как позиция после последнего элемента.

Пока этот код работает нормально и выводится 30 60. Кто-нибудь может это объяснить?

«Работает нормально» и «вывод составляет 30 60» - возможные варианты поведения, когда поведение не определено. Все это возможное поведение, когда оно не определено. Но, конечно, нет никаких гарантий, что он будет работать нормально. Что касается языка, то завтра программа может не сработать.

Я проверил это на многих онлайн-компиляторах, но вывод такой же !!

Ouput быть одинаковым на многих онлайн-компиляторах также возможно поведение, когда поведение не определено. Нет гарантии, что какой-то компилятор будет вести себя по-другому, так же, как нет гарантии, что он будет вести себя одинаково.

Независимо от того, сколько компиляторов вы пробуете, невозможно проверить правильность программы, просто выполнив ее и наблюдая результат, на который вы рассчитывали. Единственный способ доказать правильность программы - это проверить все предварительные условия и наложенные на программу инварианты.

0 голосов
/ 04 июля 2018

С std::vector::erase:

Итератор pos должен быть действительным и разыменованным. Таким образом, итератор end () (который действителен, но не может быть разыменован) не может использоваться в качестве значения для pos.

Таким образом, ваш код неверен в обоих случаях и вызывает неопределенное поведение . Это означает, что может произойти все что угодно, включая аварию, работу или что угодно.

...