Naruszenie ochrony pamięci

0

Muszę stworzyć program który losuje z listy wpisanych uczestników kilku wygranych.
Najpierw podaję liczbę uczestników (n) potem liczbę wygranych (m) następnie wpisuję uczestników oraz m liczb które oznaczają o ile miejsc ma się przesuwać wskaźnik losujący (przesuwa się od pierwszej osoby najpierw wprawo potem w lewo i tak na zmianę aż wylosuje m wygranych) osoba która zostanie wylosowana ma być usunięta z listy osób ponieważ nie może być wylosowana drugi raz, napisałem program oparty na wektorach i gdy wrzucam go na sprawdzarkę (na stronie z której mam to zadanie) to we wszystkich 5 testach jakie wykonuje dostaje komunikat naruszenie ochrony pamięci, z tego co czytałem może być to spowodowane tym że w którymś momencie mój program próbuje odczytać albo zapisać coś do pamięci która może przechowywać jakieś pliki które są poza zakresem mojego programu ale nie mogę nic znaleźć.
ktoś jest w stanie znaleźć problem tych komunikatów?
sory ale nie mogłem dodać kodu w załączniku nie wiem czemu

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

using namespace std;


    int numer=0;
    int n;
    int m;

    //zmienne do wektorów//
    int z;
    string x;


int main()
{
    cin >> n >> m;

    vector <int> wygrani;
    vector <string> osoby;

    for(int i = 0; i < n; i++)
    {
        cin >> x;
        osoby.push_back( x );
    }


     for(int i=0; i<m; i++)
     {
        cin >> z;
        wygrani.push_back( z );
     }

     z=n;
     for(int i = 0; z >= 1 && z <= 250000 && m < z && m >= 1 && i < m;i++)
     {
       if(i >= m)
       {
           break;
       }
       numer = numer + wygrani[i];
       while(numer >= n)
       {
          numer = numer - n;
       }
       cout << osoby[numer] << endl;
       osoby.erase(osoby.begin() + numer);

       n--;
       i++;

       if(i >= m)
       {
           break;
       }
       numer = numer - wygrani[i];
       while(numer < 0)
       {
        numer = numer + n;
       }
       cout<< osoby[numer] << endl;
       osoby.erase(osoby.begin() + numer);

       numer--;
       n--;

     }


    return 0;
}
0

zadanie jest tylko dostępne dla zalogowanych użytkowników na tej stronie skąd jest to zadanie treść mogę wrzucić
Joanna prowadzi własny mały serwis komputerowy, który ma świetną renomę na rynku. Właśnie dzięki temu zdobyła nowego, poważnego klienta. Jest nim Centrum Spotkania Kultur w Lublinie. Wczoraj rozpoczęła tam realizację swojego pierwszego zlecenia. W komputerze z działu biletów został uszkodzony dysk. Nasza bohaterka robi co może, aby odzyskać zapisane na nim dane.

Okazało się, że zlecenie jest bardzo pilne, a cały proces musi niestety zająć nieco czasu. Na komputerze znajdował się bowiem program, który losował szczęśliwców, którzy otrzymywali darmowe bilety na wydarzenia organizowane przez centrum. Niestety nikt nie ma jego kopii zapasowej. Joanna nie chce stracić tak ważnego klienta. Postanowiła zatem, że spróbuje rozwiązać ten problem w inny sposób.

Kierownik działu biletów wyjaśnił, jak przebiega losowanie. Na początku pracownik wprowadza listę uczestników. Następnie losowany jest ciąg liczb i zaczyna się wybieranie zwycięzców z listy. Rozpoczynając od pierwszej wprowadzonej osoby przesuwamy się po liście ku jej końcowi o ilość miejsc określoną przez pierwszą wylosowaną liczbę . Osobę na której się zatrzymamy dopisujemy do listy zwycięzców i kontynuujemy poruszanie się po liście od ostatnio wylosowanej osoby o liczbę elementów równą kolejnej wylosowanej liczbie, jednak w przeciwnym kierunku niż poprzednio. Jeżeli dotrzemy do krańca listy rozpoczynamy przeglądanie jej od przeciwnej strony. Co ważne, jedna osoba nie może zostać wybrana wiele razy. Oznacza to, że po wylosowaniu jest usuwana z listy uczestników. Wystarczy powtórzyć to działanie określoną ilość razy, aby ustalić zwycięzców. Pomóż Joannie przygotować program, który wylosuje odpowiednie osoby, żeby nie straciła klienta.
Wejście:

W pierwszej linii wejścia program otrzymuje dwie liczby naturalne n i m. Pierwsza z nich odpowiada za początkową długość listy uczestników losowania, natomiast druga za ilość osób które mają zostać wylosowane. Następnie w n liniach program otrzymuje imiona i nazwiska osób biorących udział w losowaniu. Na końcu program otrzymuje m liczb naturalnych określających o ile pól przesunąć się na liście. Program rozpoczyna działanie od pierwszej osoby która pojawiła się na wejściu w kierunku zgodnym z kierunkiem wprowadzania.
Wyjście:

Na wyjściu program powinien wyświetlić m imion i nazwisk osób które wygrały bilety.

1 ≤ n ≤ 250000

1 ≤ m < n
Przykładowe wejście:

5 4
Jan Nowak
Marcin Kowalski
Anna Zielińska
Izabela Woźniak
Wojciech Kwiatkowski
1 3 2 1

Przykładowe wyjście:

Marcin Kowalski
Izabela Woźniak
Jan Nowak
Wojciech Kwiatkowski

2

Podepnij debugger i zobaczysz co jest nie tak. A jeśli jeszcze nie korzystałeś z debuggera to już najwyższy czas aby przełamać pierwsze lody.

0

Co robi ta część kodu pomiędzy liniami 50-65?

0

ta część kodu odpowiedzialna jest za przesuwanie wskaźnika losującego w lewo

0

A fakt, nie doczytałem.

2

Ten błąd jest typowym objawem źle ustawionego wskaźnika, albo wyjechaniem poza zakres tablicy/listy.
Remedium na taki problem podał już Brat @rrowniak - odpalasz aplikację w trybie debug, bez żadnych pułapek, i czekasz kiedy się wysypie - będziesz miał pięknie pokazane na której linii się wyłożyło, a także aktualny stan zmiennych.

0

Wróżę z fusów:

  • masz tam tylko możliwość że problem stanowi odwołanie do tablicy osoby albo do tablicy wygrani
  • jako że z osoby coś usuwasz, to stawiam ze problem jest tam, ze usuwasz niektóre elementy i potem ta tablica jest coraz krótsza a ty nie bierzesz tego pod uwagę

Niemniej kod jest totalnie nieczytalny więc trudno cokolwiek więcej o nim powiedzieć. Do zaorania i napisania od nowa, tym razem w wersji dla ludzi.

2

Niepoprawnie wczytujesz dane. Nawet uruchomienie z przykładem z instrukcji to pokazuje.
Po poprawieniu powyższego output wygląda poprawnie (nie testowałem dokładniej).

0
Delor napisał(a):

Niepoprawnie wczytujesz dane. Nawet uruchomienie z przykładem z instrukcji to pokazuje.
Po poprawieniu powyższego output wygląda poprawnie (nie testowałem dokładniej).
masz rację niepoprawnie wpisywałem osoby poprawiłem to i teraz kod wygląda tak:
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int numer=0;
int n;
int m;
int y;

//zmienne do wektorów//
int z;
string x;

int main()
{
cin >> n >> m;

cin.clear();
cin.sync();

vector <int> wygrani;
vector <string> osoby;

   //Zapisanie osób//
for(int i = 0; i < n; i++)
{
    getline(cin,x);
    osoby.push_back( x );
}

 for(int i=0; i<m; i++)
 {
    cin >> z;
    wygrani.push_back( z );
 }

 y=n;
 for(int i = 0; y >= 1 && y <= 250000 && m < y && m >= 1 && i < m;i++)
 {
   if(i >= m)
   {
       break;
   }

   numer = numer + wygrani[i];
   while(numer >= n)
   {
      numer = numer - n;
   }
   cout << osoby[numer] << endl;
   osoby.erase(osoby.begin() + numer);

   n=osoby.size();
   i++;

   if(i >= m)
   {
       break;
   }
   numer = numer - wygrani[i];
   while(numer < 0)
   {
    numer = numer + n;
   }
   cout<< osoby[numer] << endl;
   osoby.erase(osoby.begin() + numer);

   n=osoby.size();
   numer--;

 }


return 0;

}
w konsoli żadnych błędów NIE MA mimo to sprawdzarka na stronie wyświetla we wszystkich testach ten sam komunikat

0

próbowałem na debugerze wyświetla mi błąd wykonania a na wyjściu wypisuje tylko jedną osobę (tą którą pierwszą na listę wpisałem bez względu na dane)

1
Kuba Lewtak napisał(a):

próbowałem na debugerze wyświetla mi błąd wykonania a na wyjściu wypisuje tylko jedną osobę (tą którą pierwszą na listę wpisałem bez względu na dane)

Jak program się zatrzyma w wyniku błędu, znajdź okno "Call Stack", przeklinaj wszystkie pozycje, gdzie widać twój kod podpatrując zawartość zmiennych we wskazanych okolicach (okienko "locals" albo nasuń myszkę nad zmienną i poczekaj chwilkę).
Prawie na pewno znajdziesz, że indeks wykracza poza zakres danych w wektorze.

1

Nadal niepoprawnie wczytujesz dane. Użyj tego debuggera!

cin >> n >> m;

Po tej instrukcji w input pozostaje znak końca linii.

0

znalazłem błąd musiałem zamieniłem getline na cin tylko że musiałem zrobić dwa wektory osobno na imiona i nazwiska i potem usuwać z dwóch wektorów to w połowie testów mam zaliczone ale w połowie przekroczenie czasu.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.