Выражение: ошибка времени выполнения векторного итератора, не допускающая отладки

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

#include <iostream>
#include <map>
#include <vector>
#include <string>

using namespace std;

int main()
{
    string s;
    map<string, int> counters;
    map<int, vector<string> > freq;

    while (cin >> s)
        ++counters[s];

    map<string, int>::const_iterator it = counters.begin();
    for (it; it != counters.end(); ++it)
    {
        freq[it->second].push_back(it->first);
    }

    for (map<int, vector<string> >::const_iterator i = freq.begin();
        i != freq.end(); ++i)
    {
        vector<string>::const_iterator j = i->second.begin();
        cout << i->first << '\t' << *j;
        while (j != i->second.end())
        {
            ++j;
            cout << ", " << *j;
        }
        cout << endl;
    }   

    return 0;
}

Программа компилируется и запускается, но всякий раз, когда я ввожу все нужные мне слова и ввожу EOF, появляется следующая ошибка времени выполнения

Выражение: векторный итератор не может быть разыменован

и тогда также появляется следующая ошибка

Стандартные библиотеки C++ вне допустимого диапазона && 0

Как это решить?


person trollpidor    schedule 18.06.2015    source источник
comment
Вы должны дополнительно объяснить, как она работает (например, она печатает все элементы, а ТОГДА выдает ошибку, или не печатает никаких элементов) и объяснить, что вы ожидаете (например, программа печатает все элементы без ошибки)   -  person Tas    schedule 19.06.2015


Ответы (2)


Я думаю, это потому, что вы разыменовываете j, когда он может указывать на end:

    cout << i->first << '\t' << *j;
                                ^----- HERE

И вот изменение, чтобы исправить это:

    if (j != i->second.end()) {
        cout << i->first << '\t' << *j;
    }
person Soheil Hassas Yeganeh    schedule 18.06.2015

Понятно.

#include <iostream>
#include <map>
#include <vector>
#include <string>

using namespace std;

int main()
{
    string s;
    map<string, int> counters;
    map<int, vector<string> > freq;

    while (cin >> s)
        ++counters[s];

    map<string, int>::const_iterator it = counters.begin();
    for (it; it != counters.end(); ++it)
    {
        freq[it->second].push_back(it->first);
    }


    for (map<int, vector<string> >::const_iterator i = freq.begin();
        i != freq.end(); ++i)
    {
        vector<string>::const_iterator j = i->second.begin();
        cout << i->first << '\t';
        for (j; j != i->second.end(); ++j)
            cout << *j << " ";

        cout << endl;
    }   

    return 0;
}

До сих пор не понимаю, почему "пока" loo[ не работает.

person trollpidor    schedule 18.06.2015
comment
Вы должны были увеличить j только после его использования. - person aslg; 19.06.2015
comment
Цикл while не работал, потому что вы увеличивали j перед его печатью, а не наоборот. И какой смысл в этом одиноком первом j в for (j; j != i->second.end(); ++j)? У вас есть это и в более раннем цикле for. - person Praetorian; 19.06.2015