• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Crash przy wychodzeniu z programu po wykonaniu części kodu

Object Storage Arubacloud
0 głosów
219 wizyt
pytanie zadane 25 grudnia 2015 w C i C++ przez Kubax96 Nowicjusz (170 p.)

Witam, tym razem mam problem, gdzie po wykonaniu części kodu (a dokładnie po wykonaniu kodu pod etykietą secondstart: (121 linia w kodzie)) wyjście z programu (nie ważne w jakim momencie) powoduje crash. Przeglądałem podobne problemy, znalazłem jedno rozwiązanie ale wydaje mi się, że jest złe. Opowiem o tym na samym końcu pod umieszczonym kodem.

W programie umieściłem etykiety: pierwsza przy menu głównym, reszta przy opcjach które wybierzemy z menu. Kod może wyglądać chaotycznie, ale dopiero zaczynam z nauką i pisaniem prostych programów, więc z góry przepraszam. Chcę dodać więcej rzeczy do mojego kodu, ale ani rusz dopóki nie poprawię błędów laugh.

Zamieszczam kod, w sumie to cały program (nie wiem co jest przyczyną błędu, wybaczcie!) niżej wraz z komentarzami.

#include <iostream>
#include <cstdlib>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>

using namespace std;

int liczba, strzal, proba, wybor;
int lotto[6];
int ile_juz_wylosowano=0;
int *wylosowane = new int[6];
bool losowanie_ok;
string answer;

int main()
{
mainmenu: // etykieta wykorzystywana do powrotu do głównego menu
    proba = 0; // wyzerowanie po zakończeniu 1 gry i powróceniu do menu
    while((wybor!=1)||(wybor!=2)||(wybor!=3))
    {
        cout << "MENU GLOWNE" << endl;
        cout << "--------------" << endl;
        cout << "1. Zgadnij o jakiej liczbie mysle" << endl;
        cout << "2. Zagraj w losowanie liczb" << endl; // po zakończeniu losowaniu liczb program crashuje przy wyłączaniu go
        cout << "3. Wyjscie" << endl;
        cout << "Wybierz opcje: ";
        cin.clear();
        cin.sync();
        cin >> wybor;
        switch(wybor)
        {
        case 1:
            goto first;
            break;
        case 2:
            goto second; 
            break;
        case 3:
            getchar();
            getchar();
            return 0;
        }
    }
first:
    system("cls");
    cout << "Witaj! Zgadnij o jakiej liczbie z przedzialu od 1 do 100 mysle." << endl;
    cout << "Gra rozpocznie sie za 5 sekund!" << endl;
    Sleep(5000);
    srand(time(NULL));
    liczba = rand()%100+1;
    system("cls");
    while(strzal!=liczba)
    {
        proba++;
        cout << "Jaka to liczba? To twoja " << proba << " proba: ";
        cin.clear();
        cin.sync();
        cin >> strzal;
        while((cin.fail()) || (strzal<=0) || (strzal>100))
        {
            cout << endl << "Podano zla wartosc! Musi byc liczba z przedzialo od 1 do 100!" << endl;
            cin.clear();
            cin.sync();
            Sleep(1000);
            cout << "Podaj liczbe ponownie, to twoja " << proba << " proba: ";
            cin >> strzal;
        }
        if(strzal==liczba)
        {
            cout << "Brawo! Odgadles moja liczbe za " << proba << " razem" << endl;
        }
        else if(strzal>liczba)
        {
            cout << "Moja liczba jest mniejsza." << endl;
        }
        else if(strzal<liczba)
        {
            cout << "Moja liczba jest wieksza." << endl;
        }
    }
    while((answer!="y") || (answer!="n"))
    {
        cout << "Chcesz wrocic do glownego menu? (y/n): ";
        cin.clear();
        cin.sync();
        cin >> answer;
        if(answer=="y")
        {
            system("cls");
            goto mainmenu;
        }
        else if(answer=="n")
        {
            getchar();
            getchar();
            return 0;
        }
    }
second: // wstep do losowania
    cout << "Wybierz 6 liczb z przedzialu od 1 do 20, a nastepnie sprawdz ile liczb odgadles!" << endl;
    while((answer!="y") || (answer!="n"))
    {
        cout << "Jestes gotow? (y/n): ";
        cin.clear();
        cin.sync();
        cin >> answer;
        if(answer=="y")
        {
            goto secondstart;
        }
        else if(answer=="n")
        {
            cout << "Za chwile powrocisz do glownego menu.." << endl;
            Sleep(3000);
            system("cls");
            goto mainmenu;
        }
    }
secondstart: // na poczatku podajemy jakie my liczby wybieramy
    srand(time(NULL));
    for(int i=0; i<=5; i++)
    {
        system("cls");
        cout << "Wpisz " << i+1 << " liczbe: ";
        cin.clear();
        cin.sync();
        cin >> lotto[i];
        while((cin.fail())||(lotto[i]<1)||(lotto[i]>20))
        {
            cout << "Podano zla wartosc! Wpisz liczbe z przedzialu od 1 do 20: ";
            cin.clear();
            cin.sync();
            cin >> lotto[i];
        }
    }
    for(int i=5; i>=0; i--) //odliczanie do losowania
    {
        system("cls");
        cout << "Losowanie nastapi za " << i  << endl;
        Sleep(1000);
    }
    system("cls");
    for (int i=1; i<=6; i++)  //losowanie liczb, które nie będą się powtarzać
    {
        do
        {
            int los=rand()%20+1;
            losowanie_ok=true;
            for (int j=1; j<=ile_juz_wylosowano; j++)
            {
                if (los==wylosowane[j]) losowanie_ok=false;
            }
            if (losowanie_ok==true)
            {
                ile_juz_wylosowano++;
                wylosowane[ile_juz_wylosowano]=los;
            }
        }
        while(losowanie_ok!=true);
    }
    cout << "Wylosowane liczby to:" << endl;
    for(int i=1; i<=6; i++)
    {
        cout << wylosowane[i] << "\a" << ", ";
        Sleep(1000);
    }
    cout << endl << endl <<"Twoje liczby to: " << lotto[0] << ", " << lotto[1] << ", " << lotto[2] << ", " << lotto[3] << ", " << lotto[4] << ", " << lotto[5] << endl;
    cout << "Liczby wylosowane to: " << wylosowane[1] << ", " << wylosowane[2] << ", " << wylosowane[3] << ", " << wylosowane[4] << ", " << wylosowane[5] << ", " << wylosowane[6] << endl;
    while((answer!="y") || (answer!="n"))
    {
        cout << "Chcesz wrocic do glownego menu? (y/n): ";
        cin.clear();
        cin.sync();
        cin >> answer; /* W tym momencie gdy wpiszemy 'n' to może zdarzyć się że 
wyjdziemy bez problemu, lecz jest to szansa na prawdę niewielka i program się 
wysypie prawie za każdym razem. Gdy klikniemy na X w rogu programu chcąc go 
wyłączyć to pojawi się informacja, że program przestał działać, czyli crash.
Gdy wrócimy do menu, a następnie będziemy chcieli wyjść wybierając 3 opcję, czyli 
Wyjście to program również scrashuje. Czemu się tak dzieje? */
        if(answer=="y")
        {
            system("cls");
            goto mainmenu;
        }
        else if(answer=="n")
        {
            getchar();
            getchar();
            return 0;
        }
    }
}

Rozwiązaniem, o którym na początku mówiłem jest wpisanie w kodzie "SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); ". Nie dostaję wtedy informacji o wysypaniu się programu, ale czy to jest dobre rozwiązanie? Ignorowanie błędu to raczej nie jest dobre rozwiązanie (tak myślę, ze ten kod ignoruje crasha i nie wyświetla go, zielony jestem) Na dodatek ten kod czasami sprawia, że zamiast wrócić do głównego menu to program wyłącza się i możliwe, że jeszcze inne błędy powoduje, ale nic innego dotychczas nie zauważyłem.

1 odpowiedź

+2 głosów
odpowiedź 25 grudnia 2015 przez adrian17 Ekspert (345,160 p.)

...na litość, każda, nawet najgorsza, książka uczy wielkimi literami: nie używaj goto oraz iteruj od 0 do N-1, a nie od 1 do N. A jednak zrobiłeś zupełnie na odwrót i w rezultacie Twój kod jest nieczytelnym bałaganem. Czegoś takiego nawet nie warto analizować.

...pozwoliłem więc kompilatorowi przeanalizować go za mnie, mogę więc podpowiedzieć że w linii 158 naruszasz pamięć. Więcej pomocy ode mnie nie oczekuj.

komentarz 25 grudnia 2015 przez Kubax96 Nowicjusz (170 p.)

masz racje, napisze od nowa to. Nie wiedziałem, żeby nie używać goto, a jeśli chodzi o iteracje, to musiałem zacząć od 1, bo gdy zaczynałem od 0 to wylosowane[0] miała wtedy kosmiczną liczbe zamiast być liczbą z przedziału od 1 do 20

komentarz 25 grudnia 2015 przez adrian17 Ekspert (345,160 p.)

bo gdy zaczynałem od 0 to wylosowane[0] miała wtedy kosmiczną liczbe zamiast być liczbą z przedziału od 1 do 20

To tylko oznacza że zrobiłeś coś źle wcześniej ;)

komentarz 25 grudnia 2015 przez Kubax96 Nowicjusz (170 p.)
coś.. no fajnie :\

Podobne pytania

0 głosów
2 odpowiedzi 140 wizyt
pytanie zadane 12 grudnia 2015 w C i C++ przez patryk16 Obywatel (1,080 p.)
0 głosów
1 odpowiedź 172 wizyt
pytanie zadane 7 września 2015 w C i C++ przez patryk16 Obywatel (1,080 p.)
0 głosów
1 odpowiedź 253 wizyt
pytanie zadane 19 kwietnia 2020 w C i C++ przez kiecam4 Nowicjusz (120 p.)

92,624 zapytań

141,482 odpowiedzi

319,824 komentarzy

62,006 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...