Segmentation fault - i brak pomysłu na niego.

0

Podczas pisania programu wywalił mi się Code Blocks. Program działał wcześniej, jednak po wywaleniu mam stale Seg. Fault. Dziwne jest to, że przed wywaleniem wszystko działało cacy. Oczywiście trochę kodu poszło w piach przez wywalenie jednak był to kod nie mieszający w tym działającym. Jeśli ktoś miałby czas spojrzeć co jest nie tak w kodzie byłbym happy.

Prosiłbym nie zwracać uwagi na bałaganiarstwo. Już miałem to poprawione wszystko ale środowisko się wywaliło.
main.c

#include"lib.h"

using namespace std;

char field[9][80];

int showmap(int A, int B, Hero *HeroCourse)
{
    for(int x=0;x<9;x++)
    {
        for(int i=0;i<80;i++)
        {
            if(A!=x || B!=i)
            {
                if(field[x][i]=='+')
                {
                    printf("\e[0;30m");cout<<field[x][i];printf("\e[0;0m");
                }
                if(field[x][i]=='^')
                {
                    printf("\e[0;33m");cout<<field[x][i];printf("\e[0;0m");
                }
                if(field[x][i]=='~')
                {
                    printf("\e[2;32m");cout<<field[x][i];printf("\e[0;0m");
                }
                if(field[x][i]=='*')
                {
                    printf("\e[2;33m");cout<<field[x][i];printf("\e[0;0m");
                }
            }
            else
            {
             switch(HeroCourse->ShowCourse()){
                case 0:{printf("\e[0;31m"); cout<<"^"; printf("\e[0;0m"); break;}
                case 1:{printf("\e[0;31m"); cout<<">"; printf("\e[0;0m"); break;}
                case 2:{printf("\e[0;31m"); cout<<"v"; printf("\e[0;0m"); break;}
                case 3:{printf("\e[0;31m"); cout<<"<"; printf("\e[0;0m"); break;}
             }
            }
        }
        cout<<endl;
    }
    return 0;
}

int readmap()
{
    FILE *in=fopen("map.txt", "rt");
    int n=0;
    while(n<9)
    {
        for(int y=0;y<80;y++)
        {
           fscanf(in,"%c", &field[n][y]);
        }
        n++;
    }
    return 0;
}

int main()
{
    Hero *Damian;
    Damian=new Hero("Dupa", 4, 15);
    readmap();
    showmap(Damian->Xcord(), Damian->Ycord(), Damian);
    actions(Damian, field);

    delete(Damian);
    return 0;
}

lib.h

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<ctime>
#include<string>
using namespace std;

//Broń
//
//
class Weapon{
    private:
        int atack;
        int range;
    public:
        bool exists;
        Weapon()
        :atack(0), range(0), exists(false)
        {}
        ~Weapon()
        {}
        int ChangeWeaponPref(int A, int R)
        {
            atack=A;
            range=R;
            exists=true;
            return 0;
        }
        int ShowAtack()
        {
            return atack;
        }
};
//Bohater
//
//
//
class Hero{

    friend class Monster;

    private:
        int Life;
        int X;
        int Y;
        string HeroName;
        Weapon HeroWeapon[4];
        int ActivWeapon;
        int Course;
    public:
        Hero()
        {
            cout<<"Błąd tworzenia postaci" <<endl;
        }
        Hero(string N, int Xlevel, int Ylevel)
        {
            HeroName=N;
            Life=30;
            X=Xlevel;
            Y=Ylevel;
            HeroWeapon[3].ChangeWeaponPref(1,1);
            Course=3;
        }
        ~Hero()
        {}
        const int Xcord();//Funkcja podająca polozenie na osi X
        const int Ycord();//Funkcja Podająca polozenie na osi Y
        int GiveWeaponUP(char TypeWeapon);//funkcja podnoszaca broń
        void ActivedWepon(int A);//funkcja zwracająca cyfrę oznaczającą wybór broni
        int AtackH(int McordX, int McordY);//funkcja odpowiedzialna za atak przeciwnika
        void MHitH();//funkcja odbierająca życie
        void ShowHeroInfo();//wszystkie info o bohaterze
        int HMove(int Xmove, int Ymove, char field[9][80]);
        int ShowLife();
        int ShowCourse();
        void HeroChangeCourse(int);

};
//Potwory
//
//
//
class Monster{

    friend class Hero;

    private:
        int Life;
        int Range;
        int X;
        int Y;
        string nameM;
    public:
        Monster()
        {
            Life=0;
            Range=0;
        }
        Monster(string N, int L, int R, int X1, int Y1)
        {
            nameM=N;
            Life=L;
            Range=R;
            X=X1;
            Y=Y1;
        }
        bool AtackM(int HcordX, int HcordY);//funkcja odpowiedzialna za atak bohatera
        void HHitM();//funkcja odbierajaca życie
};
int showmap(int A, int B, Hero *HeroCourse);
int actions(Hero *Damian, char field[9][80]);

funkction.cpp

#include"lib.h"

using namespace std;
//Funkciej klasy Hero
const int Hero::Xcord()
        {
            return X;
        }

const int Hero::Ycord()
        {
            return Y;
        }

int Hero::GiveWeaponUP(char TypeWeapon)
        {
            switch(TypeWeapon){
                case 'S':{HeroWeapon[0].ChangeWeaponPref(2,1); break;}
                case 'A':{HeroWeapon[1].ChangeWeaponPref(3,1); break;}
                case 'B':{HeroWeapon[2].ChangeWeaponPref(1,2); break;}
                default:{cout<<"Nie podniosles broni"<<endl;}
            }
            return 0;
        }
void Hero::ActivedWepon(int A)
        {
            ActivWeapon=A;
        }
int Hero::AtackH(int McordX, int McordY)
        {
            int hit;
            if(ActivWeapon==1 || ActivWeapon==0 || ActivWeapon==3)//sprawdzamy czy nie mamy broni na dystans
            {
                if((abs(McordX - X)<2) && (abs(McordY - Y)<2))//sprawdzamy dystans czy mozna oddac strzal
                {
                    srand(time(NULL));//szansa na strzal
                    hit=rand()%2;
                }

            }
            else
                if((abs(McordX - X)<3) && (abs(McordY - Y)<3))//jesli bron na dystans sprawdzamy odleglosc czy nie za daleko
                {
                    srand(time(NULL));//szansa na strzal
                    hit=rand()%2;
                }
            if(hit!=0)
                return HeroWeapon[ActivWeapon].ShowAtack();
            else
                return 0;
        }
void Hero::MHitH()
        {
            Life--;
        }
void Hero::ShowHeroInfo()
        {
            cout<<HeroName <<" znajduje się w pozycji " <<X <<" " <<Y <<". Posiada " <<Life <<" punktów życia.";
            if(HeroWeapon[0].exists==true || HeroWeapon[1].exists==true || HeroWeapon[2].exists==true)
            {
                cout<<"W jego plecaku jest";
                if(HeroWeapon[0].exists)
                    cout<<" miecz,";
                if(HeroWeapon[1].exists)
                    cout<<" topór,";
                if(HeroWeapon[2].exists)
                    cout<<" łuk,";
                cout<<"/b.";
            }
            else
            cout<<" Walczy gołymi rekoma." <<endl;
            cout<<"W dodatku bohater jest zwrócony na ";
            switch(Course){
                case 0:{cout<<"północ." <<endl; break;}
                case 1:{cout<<"wschód." <<endl; break;}
                case 2:{cout<<"południe." <<endl; break;}
                case 4:{cout<<"zachód." <<endl; break;}
            }
        }
int Hero::HMove(int Xmove, int Ymove, char field[9][80])
{   if(X+Xmove<0 || X+Xmove>8 || Y+Ymove<0 ||Y+Ymove>80)
    {
        cout<<"Nie można wykonać tak dalekiego ruchu" <<endl;
        system("sleep 1");
    }
    else
    {
        if(field[X+Xmove][Y+Ymove]!='+')
        {
            X=X+Xmove;
            Y=Y+Ymove;
        }
        else
        {
            cout<<"Nie można wykonać ruchu w wybranym przez ciebie kierunku" <<endl;
            system("sleep 1");
        }
    }
    return 0;
}

int Hero::ShowLife()
{
    return Life;
}

int Hero::ShowCourse()
{
    return Course;
}
void Hero::HeroChangeCourse(int Ncourse)
{
    Course=Ncourse;
}

//Funkcje klasy Monster
//
//

bool Monster::AtackM(int HcordX, int HcordY)
        {
            if((abs(HcordX - X)<2) && (abs(HcordY - Y)<2))
            {
                srand(time(NULL));
                bool hit=rand()%2;
                return hit;
            }
            else
            return false;
        }
void Monster::HHitM()
        {
           Life--;
        }

actions.cpp

#include"lib.h"
int actions(Hero *Damian, char field[9][80])
{
    string action="";
    int krok;
    while((action.compare("quit")!=0) && (Damian->ShowLife()>0))
    {
        getline(cin,action);
        switch((int)(action[0])){
            case 103:{
                        switch((int)(action[3])){
                            case 117:   {//w górę
                                        if((action.compare(0,5,"go up")==0))
                                            {
                                                Damian->HeroChangeCourse(0);
                                            if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))
                                                {Damian->HMove(-1,0, field);}
                                            else
                                            {
                                                krok=(48-(int)(action[action.length()-1]));
                                                Damian->HMove(krok,0,field);
                                            }
                                            }
                                            else
                                            {
                                                cout<<"Zła komenda" <<endl; system("sleep 3");
                                            }
                                            break;}
                            case 100:   {//w dół
                                        if((action.compare(0,7,"go down")==0))
                                            {
                                                Damian->HeroChangeCourse(2);
                                            if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))
                                                {Damian->HMove(1,0, field);}
                                            else
                                            {
                                                krok=((int)(action[action.length()-1])-48);
                                                Damian->HMove(krok,0,field);
                                            }
                                            }
                                            else
                                            {
                                                cout<<"Zła komenda" <<endl; system("sleep 3");
                                            }
                                            break;}
                            case 108:   {//w lewo
                                        if((action.compare(0,7,"go left")==0))
                                            {
                                                Damian->HeroChangeCourse(3);
                                            if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))
                                                {Damian->HMove(0,-1, field);}
                                            else
                                            {
                                                krok=(48-(int)(action[action.length()-1]));
                                                Damian->HMove(0,krok,field);
                                            }
                                            }
                                            else
                                            {
                                                cout<<"Zła komenda" <<endl; system("sleep 3");
                                            }
                                            break;}
                            case 114:   {//w prawo
                                        if((action.compare(0,8,"go right")==0))
                                            {
                                                Damian->HeroChangeCourse(1);
                                            if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))
                                                {Damian->HMove(0,1, field);}
                                            else
                                            {
                                                krok=((int)(action[action.length()-1])-48);
                                                Damian->HMove(0,krok,field);
                                            }
                                            }
                                            else
                                            {
                                                cout<<"Zła komenda" <<endl; system("sleep 3");
                                            }
                                            break;}
                            default:{cout<<"Zła komenda" <<endl; system("sleep 3");}
                        }
                        break;
                        }
            case 115:{if(action.compare("show info")==0)//wyswietla info o bolku
                                    {
                                        Damian->ShowHeroInfo();
                                        system("sleep 3");
                                    }
                                    break;
                    }
            case 116:{if(action.compare("turn ")!=0)//obracanie
                        {
                            if(action.compare(5,4,"back")==0)//w tył
                            {
                                switch(Damian->ShowCourse()){
                                    case 0:{Damian->HeroChangeCourse(2); break;}
                                    case 1:{Damian->HeroChangeCourse(3); break;}
                                    case 2:{Damian->HeroChangeCourse(0); break;}
                                    case 3:{Damian->HeroChangeCourse(1); break;}
                                }
                            }
                            else if(action.compare(5,4,"left")==0)//w lewo
                            {
                                if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))//tylko raz
                                {
                                    switch(Damian->ShowCourse()){
                                        case 0:{Damian->HeroChangeCourse(3); break;}
                                        case 1:{Damian->HeroChangeCourse(0); break;}
                                        case 2:{Damian->HeroChangeCourse(1); break;}
                                        case 3:{Damian->HeroChangeCourse(2); break;}
                                    }
                                }
                                else//kilka razy
                                {
                                    int x=(((int)(action[action.length()-1]))-48)%4;
                                    switch(Damian->ShowCourse()){
                                        case 0:{Damian->HeroChangeCourse(4-((4+x)%4)); break;}
                                        case 1:{Damian->HeroChangeCourse((4+(-3-x)%4)%4); break;}
                                        case 2:{Damian->HeroChangeCourse((4+(-((2+x)%4)))%4); break;}
                                        case 3:{Damian->HeroChangeCourse(3-x); break;}
                                    }
                                }
                            }
                            else if(action.compare(5,5,"right")==0)
                            {
                                if(((int)(action[action.length()-1])>58) || ((int)(action[action.length()-1])<47))//tylko raz
                                {
                                    switch(Damian->ShowCourse()){
                                        case 0:{Damian->HeroChangeCourse(1); break;}
                                        case 1:{Damian->HeroChangeCourse(2); break;}
                                        case 2:{Damian->HeroChangeCourse(3); break;}
                                        case 3:{Damian->HeroChangeCourse(0); break;}
                                    }
                                }
                                else//kilka razy
                                {
                                    int x=(((int)(action[action.length()-1]))-48)%4;
                                    switch(Damian->ShowCourse()){
                                        case 0:{Damian->HeroChangeCourse(x); break;}
                                        case 1:{Damian->HeroChangeCourse((1+x)%4); break;}
                                        case 2:{Damian->HeroChangeCourse((2+x)%4); break;}
                                        case 3:{Damian->HeroChangeCourse((3+x)%4); break;}
                                    }
                                }


                            }
                        }
            }
        }
        system("clear");
        showmap(Damian->Xcord(), Damian->Ycord(), Damian);
    }
    return 0;
}
0

Nie wiem czy ktoś rzuci okiem dla relaksu i to sprawdzi, tym bardziej, że ten błąd pojawia się w readmap() czyli tam gdzie jest czytanie jakiegoś pliku, który nie wiadomo co zawiera. Do obsługi plików możesz też skorzystać z ifstream/ofstream.

0

Już mówię. Plik zawiera serię znaków. Po 80 w wierszu. Wierszy 9. Brzegi to były +, a to co w środku nie grało róznicy (mogły być spacje. ja miałem wsadzone ~,^ i *). (to akurat babol o jakim wspomniałem. :) jeszcze podlegać to będzie optymalizacji tak samo jak to, że tablica, do której wczytyje jest chwilowo globalna). Znając siebie istnieje tutaj przepełnienie stosu, jednak podczas pracy ani razu nie miałem takiego błędu. Dopiero po wywaleniu się środowiska otrzymałem błąd.

EDYTKA
Błąd znaleziony. Okazało się, że plik z którego wczytuję mi uciekł. I brawo mam za swoje, że nie wstawiam kontroli obecności pliku :/.

@Do obsługi plików możesz też skorzystać z ifstream/ofstream.

Jakoś wolę dostawać się do plików w sposób znany i z C, jednak już widzę jakie w przyszłości mam z tym problemy.

Przepraszam za niepotrzebną panikę.
Pozdrawiam.

0

Użyj debuggera! Masz gdb (nie zapomnij skompilować programu z -ggdb). Pomocne są też: splint i valgrind. Nieco mniej zabawny w użyciu jest strace i ltrace. Dostępnych jest mnóstwo narzędzi, skorzystaj z nich.

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