[C++] Problem "program przestał działać"


(Sikora Michal) #1

witam, jestem w totalnej kropce, wywala mi ciągle że program przestał dzialać i windows szuka błędów. 

 

wszystkie funkcje operujące na liscie są zabezpieczone przed wyjściem poza nią, wiec totalnie nie wiem dlaczego program nie chce dzialać. Kompilator nie wyrzuca żadnych błędów. dodam że jestem początkującym programistą wszelkie wskazówki mile widziane :slight_smile:

 

dodaje kod w pliku txt :slight_smile:

 

//a ja wrzucam ten plik do posta // drobok

include

include

include

include

include

using namespace std;

/*W ramach zadania p2 do programu p1 prosze stworzyc i wykonac nastepujace funkcje:

Tworzenie listy w funkcji

Wyznaczyc i wypisac srednie wartosci liczba_1, liczba_2 oraz róznicy pomiedzy tymi wartosciami.
Na poczatku listy dodac rekord o srednich wartosciach.

Funkcje usuwajaca z listy rekordy, w których wartosc bezwzgledna róznicy pomiedzy liczba_1 i liczba_2
jest wieksza od sredniej róznicy. Dodac na koncu listy rekord z nowymi srednimi wartosciami liczba_1 i liczba_2.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Przy usuwaniu elementów o wartosci bezwzglednej róznicy wiekszej niz srednia wartosc róznicy mam wrazenie,
ze sa usuwane nie te rekordy, co trzeba. Dodatkowo jest zly warunek – powinna byc wartosc bezwzgledna róznicy,
a nie poszczególnych elementów.
Na koncu listy nie zapisuje Pan nowych wartosci srednich.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/

struct SElement
{
int liczba1,liczba2;
SElement *nast;
};

int srednia_roznica;

SElement *glowa, *aktualny, *ogon;
int templiczba1, templiczba2, ile;

void dodaj(int x,int y)
{

aktualny = new SElement;
aktualny->liczba1 =x;
aktualny->liczba2 =y;
aktualny->nast = glowa->nast;
glowa->nast = aktualny;
};

void lista()
{
int licz1=1,licz2=0;

licz1=1+rand()% 100;
licz2=1+rand()% 100;

templiczba1 =licz1;
templiczba2=licz2;

glowa = new SElement;
glowa->liczba1=licz1;
glowa->liczba2=licz2;
glowa->nast = NULL;
ogon = glowa;

ile=1;

if(licz1!=licz2)

{

do
{
ile++;

licz1=1+rand()% 100;
licz2=1+rand()% 100;

templiczba1+=licz1;
templiczba2+=licz2;

aktualny = new SElement;
aktualny->liczba1=licz1;
aktualny->liczba2=licz2;
aktualny->nast = NULL;
ogon->nast = aktualny;
ogon = aktualny;

}
while(licz1!=licz2);

};

int sr1=templiczba1/ile;
int sr2=templiczba2/ile;
cout<<endl<<endl<<"srednia wartosc x = "<<sr1<<endl;
cout<<endl<<endl<<"srednia wartosc y = "<<sr2<<endl<<endl;
cout<<endl<<endl<<"roznica miedzy nimi = "<<sr1-sr2<<endl<<endl;

aktualny = new SElement;
aktualny->liczba1 =sr1;
aktualny->liczba2 =sr2;
aktualny->nast = glowa;
glowa= aktualny;

srednia_roznica = sr1-sr2;

}

void pisz(SElement *adres)
{
if (!adres)
return;
cout <liczba1 <<","<liczba2<< endl;
pisz(adres->nast);
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*Funkcje usuwajaca z listy rekordy, w których wartosc bezwzgledna róznicy pomiedzy liczba_1 i liczba_2
jest wieksza od sredniej róznicy. Dodac na koncu listy rekord z nowymi srednimi wartosciami liczba_1 i liczba_2.

Przy usuwaniu elementów o wartosci bezwzglednej róznicy wiekszej niz srednia wartosc róznicy mam wrazenie,
ze sa usuwane nie te rekordy, co trzeba. Dodatkowo jest zly warunek – powinna byc wartosc bezwzgledna róznicy,
a nie poszczególnych elementów.
Na koncu listy nie zapisuje Pan nowych wartosci srednich.*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int srx(SElement*adres)
{
int ile=0,licz1=0;
while(adres!=NULL)
{
ile++;
licz1+=adres->liczba1;
adres=adres->nast;

}
int x=licz1/ile;

return x;
}

int sry(SElement*adres)
{
int ile=0,licz1=0;
while(adres!=NULL)
{
ile++;
licz1+=adres->liczba2;
adres=adres->nast;

}
int x=licz1/ile;

return x;
}

const int bezwgl_roz=abs(srx(glowa)-sry(glowa));

int sr_roz(SElement*adres)
{
int srednia=0,ile=0;
while(adres!=NULL)
{
ile++;
srednia+=adres->liczba1 - adres->liczba2;

    adres=adres->nast;
}
return srednia/ile;

}

const int SREDNIA_ROZNICA=sr_roz(glowa);

void usun(int ktory_nr)
{

 aktualny = glowa;
for (int i=1; i != ktory_nr; i++)
  aktualny = aktualny->nast;

ogon = aktualny->nast;
aktualny->nast = ogon->nast;
delete ogon;

};

void usun_rekordy(SElement*adres)
{
int ile_usun_rekordy=0;

    while(adres!=NULL)
    {
        ile_usun_rekordy++;

        if(bezwgl_roz>SREDNIA_ROZNICA)
        {
            aktualny = glowa;
            ogon = aktualny->nast;
            aktualny->nast = ogon->nast;
            delete ogon;
        }
            adres=adres->nast;


    }

}

int main()
{
cout<<"POCZATKOWA LISTA"<<endl<<endl<<endl;

lista();
cout<<"(x),(y)"<<endl<<endl;//to tylko tak dla kosmetyki :slight_smile:
pisz(glowa);

usun_rekordy(glowa);
cout<<endl<<endl<<endl;
pisz(glowa);

/*////////////////////////////////////////////////////////////////////////
//ZMIANY//
///////////////////////////////////////////////////////////////////////
int x,y;
cout<<endl<<endl<<endl<<"WPROWADZAMY NOWA WARTOSC NA 2 POZYCJI";
cout<<endl<<endl<<"jaka wartosc wprowadzic do x: ";
cin>>x;
cout<<endl<<"jaka wartosc wprowadzic do y: ";
cin>>y;

dodaj(x,y);
cout<<endl<<endl<<endl<<"USUNIETO ROWNIEZ 4 ELEMENT LISTY";
cout<<endl<<endl<<endl<<"LISTA PO ZMIANACH"<<endl<<endl<<endl;

usun(3);
pisz(glowa);

cout<<endl<<endl<<endl;

*/

///////////////////////////////////////////////////////////////////////
//KASACJA//
//////////////////////////////////////////////////////////////////////
aktualny = glowa;
while (aktualny)
{
glowa=aktualny;
aktualny=aktualny->nast;
//cout << "Kasuje: " <liczba1 <<","<liczba2<< endl;
delete glowa;
//Sleep(20); // tak zeby wygladalo bardziej profesjonalnie :stuck_out_tongue:
};
glowa = NULL;

return 0;
};

problem.txt


(pionner) #2

Od razu po uruchomieniu z odpalonym debuggerem wywaliło “Unhandled exception at 0x00007ff7f23315a5 in lab.exe: 0xC0000094: Integer division by zero.”

W skrócie w 142 linii (int x=licz1/ile;) ile było ustawione na 0, więc próbowałeś dzielić przez 0.

 

W czym kompilujesz?


(Sikora Michal) #3

 

w code blocks

 

po zamianie z zera na jeden i odjęciu w int x=licz1/ile-1; nadal wywala program :confused: chyba zaczne od nowa :frowning:


(Drobok) #4

(hindus) #5

Wywala z tym samym błędem?


(Sikora Michal) #6

tak, a co do tego przed edycją :wink: jest inkrementacja, poza tym nie wiem czy podejście że winą jest dzielenie przez 0 powoduje błąd :confused: przecież ile jest inkrementowane w while.

 

na szczęście zrobiłem już ten program na piechotę bez użycia funkcji, ale nadal nie wiem (a chciałbym się dowiedzieć) dlaczego wywalało cały program :confused: tak żeby na przyszłość wiedzieć


(mikolaj_s) #7

Co ci da dodanie -1?  I tak gdy nie masz elementów w liście dzielisz przez zero. Sprawdż pod koniec czy ile jest zerem i zwróć ten -1 jak chcesz, a gdy nie jest zwracaj średnią.

PS. przed dzieleniem zawsze sprawdzaj czy nie dzielisz przez zero, chyba, że jesteś pewien, że dzielnik nie może być zerem.


(Sikora Michal) #8

Wskazówka bardzo dobra dzięki :slight_smile: ale pytanie takie: jakim cudem mogę dzielić przez zero jeżeli lista musi mieć co najmniej jeden element i wynika to z jej budowy, a pętla jest typu white czyli najpierw sprawdzany jest warunek a potem wykonywana treść. Jęli w pierwszej kolejności w pętli dodaje do “ile” jeden to potem już jest co najmniej mniej jeden wiec nie dziele przez zero. (Nie kluce się, ja się dopiero uczę :wink: )


(mikolaj_s) #9

A nie zastanowiło Cię dlaczego program rzuca od razu problem floating point exception, zanim uruchomi się funkcja main? Ten błąd oznacza błąd dzielenia przez zero (lub reszty z dzielenia). Przyjrzyj się dokładnie swojemu kodowi, powinnieś szybko znaleźć gdzie jest problem. A tak na przyszłość to skąd pomysł na wywoływanie funkcji poza funkcji main?

PS. Dlaczego napisałeś, że program jest C++ skoro kod jest mieszaniną C i C++? :smiley:


(Sikora Michal) #10

dzięki za wskazówki mikolaj_s przydadzą się bardzo, no i dzięki wszystkim którzy starali się pomóc :slight_smile: kolejna cegiełka dodana :wink: dzieki