Naruszenie ochrony pamięci

Odpowiedz Nowy wątek
2019-04-09 18:03
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;
}
edytowany 2x, ostatnio: kq, 2019-04-09 19:32
Daj linka do oryginalnego zadania, bo opis Masz dość lakoniczny. - lion137 2019-04-09 18:24

Pozostało 580 znaków

2019-04-09 19:11
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

Pozostało 580 znaków

2019-04-09 19:40
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.


Pozostało 580 znaków

2019-04-09 21:51
0

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

edytowany 1x, ostatnio: Delor, 2019-04-09 21:51

Pozostało 580 znaków

2019-04-09 21:56
0

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

Pozostało 580 znaków

2019-04-09 22:00
0

A fakt, nie doczytałem.

Pozostało 580 znaków

2019-04-10 09:16
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.


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]

Pozostało 580 znaków

2019-04-10 10:13
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.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2019-04-10 10:18
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).

edytowany 1x, ostatnio: Delor, 2019-04-10 10:24

Pozostało 580 znaków

2019-04-10 18:41
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

bo "konsola" nie wykryje błędów semantycznych :) - au7h 2019-04-10 18:45
Czyli nie uruchomisz debuggera za żadne skarby? - rrowniak 2019-04-10 19:31

Pozostało 580 znaków

2019-04-10 20:20
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)

zamień getline() na zwykłe cin (kosztem wczytywania tylko do białego znaku) i zobacz co się stało się - au7h 2019-04-10 21:10

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0