Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Vector subscript out of range

Ostatnio zmodyfikowano 2016-12-02 23:50
Autor Wiadomość
tomo6916
Temat założony przez niniejszego użytkownika
[C++] Vector subscript out of range
» 2016-12-02 17:15:23
Dzień dobry. Mam problem z moim programem (program oblicza liczbę mandatów uzyskanych przez partie w wyborach metodą D'Hondta); gdy uruchamiam go poprzez plik wykonywalny .exe, to wyskakuje mi komunikat o treści "vector subscript out of range". Kompilator nie wykrywa żadnych błędów. Wiem, że ten komunikat pojawia się, gdy odwołujemy się do nieistniejących elementów/przekraczamy rozmiar wektora. Nie jestem jednak w stanie znaleźć źródła problemu w moim kodzie.

C/C++
int main()
{
    string wejscie = "wejscie.txt";
    string wyjscie = "wyjscie.txt";
   
    //odczytanie danych z pliku wejsciowego
    ifstream odczyt( wejscie );
    int dane;
    vector < int > wektor_danych; //wektor, ktory bedzie przechowywac dane odczytane z pliku wejsciowego
    int i = 0;
    while( odczyt >> dane )
    {
        wektor_danych.push_back( dane );
        i++;
    }
   
    const int liczba_partii = wektor_danych.size() - 1; //liczba_partii - stala przechowujaca liczbe partii
   
    vector < int > ilorazy_wyborcze; //wektor, ktory bedzie przechowywal ilorazy wyborcze kazdej z partii
   
    //uzupelnianie wektora o liczby glosow na poszczegolne partie (liczba glosow oddana na partie jest jej pierwszym ilorazem wyborczym)
    for( int i = 0; i < liczba_partii; i++ )
    {
        ilorazy_wyborcze.push_back( wektor_danych[ i + 1 ] );
    }
   
    const int liczba_mandatow = wektor_danych[ 0 ]; //liczba_mandatow - stala przechowujaca liczbe mandatow mozliwych do zdobycia w wyborach
   
    vector < int > mandaty; //wektor, ktory bedzie przechowywal liczbe mandatow zdobyta przez kazda partie
   
    //zerowanie wektora mandaty, zeby dane w nim zawarte mialy jakas wartosc poczatkowa, ktora potem bedziemy zwiekszac, liczac mandaty zdobyte przez kazda partie
    for( int i = 0; i < liczba_partii; i++ )
    {
        mandaty.push_back( 0 );
    }
   
    //obliczanie liczy mandatow zdobytych przez kazda partie
    int max = 0; //zmienna, ktora bedzie sluzyc do wyszukiwania maksymalnego ilorazu wyborczego
    int imax = 0; //zmienna, ktora bedzie sluzyc do wyszukiwania adresu maksymalnego ilorazu wyborczego w wektorze glosow
   
    vector < int > wektor_glosow; //wektor, ktory bedzie przechowywal liczbe glosow oddanych na poszczegolna partie
   
    //uzupelnianie wektora o liczby glosow na poszczegolne partie
    for( int i = 0; i < liczba_partii; i++ )
    {
        wektor_glosow.push_back( ilorazy_wyborcze[ i ] );
    }
   
    //przydzielanie mandatow partiom
    for( int i = 0; i < liczba_mandatow; i++ )
    {
        for( int j = 0; j < liczba_partii; j++ )
        {
            if( ilorazy_wyborcze[ j ] > max ) //wyszukiwanie maksymalnego ilorazu wyborczego i jego adresu w wektorze glosow
            {
                max = ilorazy_wyborcze[ j ];
                imax = j;
            }
            for( int k = 0; k < liczba_partii; k++ ) //badanie, czy podczas przydzialu i-tego mandatu istnieja partie, ktore maja taki sam iloraz wyborczy
            {
                if( ilorazy_wyborcze[ k ] == max && k != j && wektor_glosow[ k ] > wektor_glosow[ j ] )
                {
                    max = ilorazy_wyborcze[ k ]; //jesli jakies partie maja taki sam iloraz wyborczy, to mandat otrzymuje ta partia, na ktora zaglosowalo wiecej osob
                    imax = k;
                }
            }
        }
        mandaty[ imax ] ++; //przydzielenie mandatu partii z najwiekszym ilorazem wyborczym
        ilorazy_wyborcze[ imax ] = ilorazy_wyborcze[ imax ] * mandaty[ imax ] /( mandaty[ imax ] + 1 ); //obliczenie nowego ilorazu wyborczego dla partii, ktorej wlasnie przydzielono mandat
        max = 0; //wyzerowanie najwiekszej wartosci sposrod ilorazow wyborczych
    }
   
    //zapis wynikow glosowania do pliku wyjsciowego
    ofstream zapis( wyjscie );
   
    zapis << "--------WYNIKI GLOSOWANIA--------\n\nSposrod " << liczba_mandatow << " mandatow, partie uzyskaly nastepujaca liczbe mandatow:\n\n";
    for( int i = 0; i < liczba_partii; i++ )
    {
        zapis << "partia nr " << i + 1 << ":\t" << mandaty[ i ] << endl;
    }
   
   
    return 0;
}
P-154408
carlosmay
» 2016-12-02 17:21:46
Im wcześniej zaczniesz korzystać z debuggera, tym lepiej.
Tak szuka się błędów w czasie wykonywania programu.

edit: co mogę Ci poradzić:
Podziel kod na funkcje, bo tego kodu nie da się sprawnie czytać.

program oblicza liczbę mandatów uzyskanych przez partie w wyborach metodą D'Hondta
Opisuj oczekiwane działanie programu. Nie każdemu chce się zagłębiać w wybraną metodę (jestem leniwy).
P-154409
Gibas11
» 2016-12-02 19:49:26
@up
Opisuj oczekiwane działanie programu. Nie każdemu chce się zagłębiać w wybraną metodę (jestem leniwy).
Jakby trzeba było, takie błędy są z reguły oczywiste i powstają w efekcie niedopatrzenia, to tylko wyjście poza zakres vectora.

@OP
C/C++
for( int i = 0; i < liczba_partii; i++ )
{
    ilorazy_wyborcze.push_back( wektor_danych[ i + 1 ] );
}
1. wykraczasz poza zakres vectora
wektor_danych
.
2. Dane kopiuje się między kontenerami używając std::copy:
std::copy( vec1.begin(), vec1.end(), std::back_inserter( vec2 ) );
P-154415
tomo6916
Temat założony przez niniejszego użytkownika
» 2016-12-02 20:21:41
Hmmm, nie widzę tego. Wektor
wektor_danych
 ma rozmiar o 1 większy niż wartość
liczba_partii
. Przykładowo, gdy
liczba_partii
 jest równa 3, to
wektor_danych
 ma rozmiar 4. Wspomniana pętla for wykona się po raz ostatni dla i=2, a wtedy
wektor_danych[ i + 1 ]
 to
wektor_danych[ 3 ]
, czyli nie wykraczam poza zakres. A przynajmniej tak mi się wydaje. Czy coś mi tutaj umyka? W każdym razie dziękuję za odpowiedź, spróbuję skopiować dane przy użyciu std::copy.
P-154416
Gibas11
» 2016-12-02 20:27:40
No rzeczywiście. ;-; Reszta kodu już taka prosta nie jest, więc też odsyłam do debuggera. A tak btw dlaczego pomijasz w tamtej pętli pierwszy element vectora z 'danymi'?
@down Nie do końca chodzi o wartości zmiennych, w moim przypadku program wysypuje się tylko jeśli nie znajdzie pliku, inaczej debugger nie zająknął się ani słowem. A problem jest tu:
const int liczba_mandatow = wektor_danych[ 0 ];
Bo nie ma sprawdzania czy vector nie jest pusty. Chyba że nie działa jeszcze coś, u mnie nic więcej nie ma.
P-154418
j23
» 2016-12-02 20:29:30
Odpal program pod kontrolą debuggera. Jeśli wyskoczy Ci wyjątek, użyj okna call stack do zlokalizowania miejsca wystrzału w twoim kodzie. Będziesz wiedział, przy jakich wartościach zmiennych dochodzi do wyjątku, a stąd prosta droga do rozwiązania problemu.
P-154419
tomo6916
Temat założony przez niniejszego użytkownika
» 2016-12-02 20:32:27
Ponieważ w moim pliku wejściowym
wejscie.txt
 zapisane są dane w następujący sposób: pierwszą wartością jest liczba miejsc z parlamencie, a następnie podawane są rozdzielone
spacjami liczby głosów uzyskane przez partie.
Zapomniałem o tym wspomnieć - mój błąd.
@Gibas11 rzeczywiście, błąd jest w tym miejscu. Co dokładnie powinienem zrobić, żeby uniknąć tego błędu?
P-154420
Gibas11
» 2016-12-02 22:27:12
Sprawdź czy cokolwiek jest w vectorze z danymi (np.
if( !wektor_danych.size() ) { std::cout << "pusto ;-;\n"; }
 i jeśli nie – wyświetl jakiś komunikat o błędzie i zakończ program, bo i tak nie ma co robić.
P-154424
« 1 » 2
  Strona 1 z 2 Następna strona