CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Niezidentyfikowany błąd (praca z klasami)

Niezidentyfikowany błąd (praca z klasami)

dział ogólny

Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez Arnold_S » środa, 21 lutego 2018, 20:50

Witam!
Wstępnie udało mi się stworzyć fajną aplikację pracującą na klasach. Niestety program nie działa stabilnie. Mam bardzo duży problem ze zidentyfikowaniem błędu ponieważ nie jest to błąd "ortograficzny", tzn. kompilator wszystko akceptuje. Nie widać tam błędów, kompilacja przebiega bez zastrzeżeń, mimo wszystko gdy wciskam główny przycisk "LOSUJ POSTAĆ", na przykład 15 razy to od czasu do czasu...ale nie zawsze aplikacja się zawiesza. Muszę zamykać proces ponieważ nic innego nie da się zrobić.
Program napisałem w RadStudioXE2, a także testowałem w CodeBlocks (po małym przerobieniu klas tak aby informacje zostały wysyłane do strumienia cout w konsoli.).
Ogólnie program działa bez zarzutu. Niestety tak jak napisałem wyżej raz na jakiś czas pojawia się poważny błąd. Próbowałem debugować w codeblocks-ie. Uruchamiałem tą apkę w debuggerze linijka po linijce i wydaje się wszystko wporządku. Wygląda to tak jakby raz na jakiś czas nie udało się zaalokować pamięci dla dynamicznie tworzonego obiektu klasy i już na samym początku zawiesza się program zanim wypełni pola klasy.
Tylko raz, może dwa razy na sto prób wyskoczył mi błąd "Access violation" więc być może problem dotyczy jakiegoś wskaźnika. Miejsc gdzie wskaźnikowo używam tablicy mam dosłownie kilka. Sprawdzałem je kilkukrotnie i wydaje mi się, że jest naprawdę wporządku.
Bardzo proszę o pomoc. Nie potrafię odnaleźć w którym miejscu tego mechanizmu pojawia się problem. Czuję, że jest to problem leżący wewnątrz jednej z klas, gdzie dynamicznie tworzę obiekt klasy pomocniczej aby pracować na jej danych. Przyglądałem również to miejsce 9348593845938 razy, szukałem odpowiedzi w książkach ale wydaje mi się, że jest zgodnie ze sztuką... :( Jestem zrozpaczony bo zrobiłem kupę roboty i nie potrafię dostrzec problemu...

Problem objawia się takim podpisem:
Nazwa zdarzenia problemu: AppHangB1
Nazwa aplikacji: Project1.exe
Wersja aplikacji: 1.0.0.0
Sygnatura czasowa aplikacji: 00000000
Podpis zawieszenia: 4184
Typ zawieszenia: 0
Wersja systemu operacyjnego: 6.1.7601.2.1.0.256.1
Identyfikator ustawień regionalnych: 1045
Dodatkowy podpis zawieszenia 1: 41844279fda6391953ab4353f4c7e646
Dodatkowy podpis zawieszenia 2: 4d82
Dodatkowy podpis zawieszenia 3: 4d82cb1fd888019a4afd54106269355e
Dodatkowy podpis zawieszenia 4: 4184
Dodatkowy podpis zawieszenia 5: 41844279fda6391953ab4353f4c7e646
Dodatkowy podpis zawieszenia 6: 4d82
Dodatkowy podpis zawieszenia 7: 4d82cb1fd888019a4afd54106269355e


Zdaję sobie sprawę, że niewiele to może mówić bo przeszukałem chyba cały internet i odpowiedzi nijak się mają do zaistniałej sytuacji.
Oczywiście nie liczę na to, że ktoś odnajdzie błąd za mnie. Poprostu mam za małe doświadczenie i brak mi zmysłu gdzie może leżeć przyczyna.
Może gdybym mógł z Waszą pomocą zrobić taki mały remanent relacji tych klas oraz tak z grubsza co one robią, któryś Was wpadłby na jakiś konkretny pomysł.
Byłbym bardzo wdzięczny!

/edit program, który tworzę nie służy do celów komercyjnych jest projektem tworzonym w celu podszkolenia się w pracy z klasami, a tematyka jest związana z moją drugą pasją :)

Proszę napiszcie czy mogę liczyć na pomoc, to dalej rozwinę temat odnośnie klas.
Pozdrawiam.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez polymorphism » czwartek, 22 lutego 2018, 11:20

Dużo napisałeś, ale podałeś mało konkretów. Jedyne co mogę napisać, to to, że jeśli aplikacja się zawiesi, użyj debuggera do lokalizacji miejsca, w którym program się "kręci". Nie wiem, jak to wygląda w C++ Builderze, ale w Code Blocks możesz podpiąć się pod proces debuggerem (Attach to process).

Tylko raz, może dwa razy na sto prób wyskoczył mi błąd "Access violation" więc być może problem dotyczy jakiegoś wskaźnika.

Albo piszesz poza zakresem jakiejś tablicy... powodów może być wiele. Generalnie we współczesnym C++ ręcznie nie zarządza się pamięcią, używa się std::unique_ptr lub std::shared_ptr (w parze z std::make_unique() i std::make_shared()) i std::vector.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2164
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 199
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez Arnold_S » czwartek, 22 lutego 2018, 19:16

Zaraz zacznę zabawę z debuggerem. Chyba wpadłem na trop. Spróbuję swoich sił. Jeśli wypali mi mózg to wrócę i wyłożę problem znacznie dokładniej. Dzięki za podpowiedź!

/edit
Zlokalizowałem 2 błędy. Narazie zająłem się pierwszym gdyż dokładnie wiem gdzie się zaczyna.

Problem dotyczy obiektu klasy "krasnolud".
W funkcji main (w code blocks), tworzę go dynamicznie i przypisuje do wskaźnika abstrakcyjnej klasy "postać". Z uwagi na to, że problem czasem się pojawia za 1 razem a czasem za 38, to umieściłem ten fragment w pętli.
KOD cpp:     UKRYJ  
 for(int i=0; i<30; i++) { postac *wskaznik = new krasnolud(0,0); }


W klasie chodzi o to, że na jej podstawie tworzy się postać krasnoluda. W konstruktorze wywołuję funkcje po kolei, które losują dla niego różne cechy, jak: wzrost, wagę, wiek, imię, ...i jeszcze kilkanaście innych oraz feralną funkcję, która losuje dla niego opis wyglądu. Dzięki temu może mieć dodatkowe cechy wyglądu, np. pulchne policzki albo jedno oko, które spowoduje, że zmniejszą się jego umiejętności strzeleckie...nie chcę się rozpisywać, do rzeczy.

Fragment konstruktora klasy krasnolud:
KOD cpp:     UKRYJ  
krasnolud(bool dod1 = false, bool dod2 = false)
{
        rasa = "Krasnolud";

        //zerowanie składników klasy
        zeruj_all(); //funkcja zeruje wszystkie składniki prywatne

        //losowanie współczynników postaci
        losuj_plec();
        losuj_wiek();
        losuj_wzrost();
        losuj_wlosy();
        losuj_charakter();
        losuj_oczy();
        losuj_opis();  //<-------  TO JEST FUNKCJA POWODUJĄCA PIERWSZY BŁĄD!!
        //...i jeszcze kilka innych funkcji wypełniających cechy
}
 

Funkcja losuj opis powoduje błąd. Właściwie to pętla for() w niej zawarta. Czasem, raz na jakiś czas poprostu obraca się w nieskończoność. Z bliżej nie znanych mi przyczyn.
Przedstawię ją poniżej. Proszę przeczytaj komentarze.
KOD cpp:     UKRYJ  
void krasnolud::losuj_opis(void)
{
        std::string opis2;       //tymczasowy obiekt na którym pracuję w tej funkcji
        std::string::size_type pozycja;  //przechowuje numer pozycji znalezionego stringu
        y = rzut_kostka(K3);    //losujemy ile ta postać ma mieć cech - K3. Możwliwe wyniki 1,2,3.
        x = 0;                        //składnik prywatny klasy tutaj go tylko zeruję, za chwilę będę z niego korzystał          
        unsigned short int ostatnio[3] = {0, 0, 0}; //tymczasowa tablica- przechowuje 3 rzuty kostką.

        //wypełniam tablicę rzutami kostką pilnując aby każdy rzut był inny
        for(int i=0; i<y; i++)
        {
                if(i == 0) { ostatnio[0] = rzut_kostka(K100); }
                if(i == 1)
                {
                        do{ ostatnio[1] = rzut_kostka(K100); }
                        while(ostatnio[1] == ostatnio[0]);
                }
                if(i == 2)
                {
                        ostatnio[2] = rzut_kostka(K100);
                        if( (ostatnio[2] != ostatnio[1]) && (ostatnio[2] != ostatnio[0]) )
                        { continue; }
                        else
                        {
                                ostatnio[2] = rzut_kostka(K100);
                                --i;
                        }
                }
        }
        // poniżej losowanie cech z kontrolą wystapnienia dwóch przeciwstawnych, np. krasnolud z bujną czupryną
        // nie może mieć cechy "łysy" lub też jeśli psotać jest kobietą to nie może mieć wąsów!!
        for(int i=0; i<y; i++) //<----- ta pętla czasem obraca się w nieskończoność                               
        {
                x = ostatnio[i];
                if(x <= 2                )                      { if( (pozycja = opis2.std::string::find("duży nos")) == std::string::npos )
                                                                        { opis2 += "duży nos";                                 }
                                                                        else    { --i; }                                                }

                else if(x> 2 && x <= 4)         { if( (pozycja = opis2.std::string::find("płaski nos")) == std::string::npos )
                                                                        { opis2 += "płaski nos";                               }
                                                                        else    { --i; }                                                }

                else if(x> 4 && x <= 6)         { if( (pozycja = opis2.std::string::find("wysokie czoło")) == std::string::npos )
                                                                        { opis2 += "wysokie czoło";                            }
                                                                        else    { --i; }                                                }

                else if(x> 6 && x <= 8)         { if( (pozycja = opis2.std::string::find("haczykowaty")) == std::string::npos )
                                                                        { opis2 += "haczykowaty nos";                   }
                                                                        else    { --i; }                                                }

                else if(x> 8 && x <= 10)                { if( (pozycja = opis2.std::string::find("pulchne policzki")) == std::string::npos )
                                                                        { opis2 += "pulchne policzki";                  }
                                                                        else    { --i; }                                                }

                else if(x> 10 && x <= 12)       { if( (pozycja = opis2.std::string::find("gniewne czoło")) == std::string::npos )
                                                                        { opis2 += "gniewne czoło";                            }
                                                                        else    { --i; }                                                }

                else if(x> 12 && x <= 14)       { if( (pozycja = opis2.std::string::find("oko mniejsze")) == std::string::npos )
                                                                        { opis2 += "jedno oko mniejsze";                }
                                                                        else    { --i; }                                                }

                else if(x> 14 && x <= 16)       { if( ((pozycja = opis2.std::string::find("owłosione dłonie")) == std::string::npos ) &&
                                                                                ( plec != "K" )                                 )
                                                                        { opis2 += "owłosione dłonie";        }
                                                                        else    { --i; }                                                }

                else if(x> 16 && x <= 18)       { if( (pozycja = opis2.std::string::find("pokaźne uszy")) == std::string::npos )
                                                                        { opis2 += "pokaźne uszy";                             }
                                                                        else    { --i; }                                                }

                else if(x> 18 && x <= 20)       { if( (pozycja = opis2.std::string::find("mruganie")) == std::string::npos )
                                                                        { opis2 += "częste mruganie";                  }
                                                                        else    { --i; }                                                }

                else if(x> 20 && x <= 22)       { if( (pozycja = opis2.std::string::find("gładka cera")) == std::string::npos )
                                                                { opis2 += "gładka cera";                              }
                                                                else    { --i; }                                                }

                else if(x> 22 && x <= 24)       { if( (pozycja = opis2.std::string::find("rozst.oczy")) == std::string::npos )
                                                                        { opis2 += "szer.rozst.oczy";                   }
                                                                        else    { --i; }                                                }

                else if(x> 24 && x <= 26)       { if( (pozycja = opis2.std::string::find("dobrze zbudowany")) == std::string::npos )
                                                                        { opis2 += "dobrze zbudowany";                  }
                                                                        else    { --i; }                                                }

                else if(x> 26 && x <= 28)       { if( (pozycja = opis2.std::string::find("duży brzuch")) == std::string::npos )
                                                                        { opis2 += "duży brzuch";                              }
                                                                        else    { --i; }                                                }

                else if(x> 28 && x <= 30)       { if( (pozycja = opis2.std::string::find("wąsko rozst.oczy")) == std::string::npos )
                                                                        { opis2 += "wąsko rozst.oczy";                 }
                                                                        else    { --i; }                                                }

                else if(x> 30 && x <= 32)       { if( (pozycja = opis2.std::string::find("koślawe")) == std::string::npos )
                                                                        { opis2 += "koślawe kolana";                   }
                                                                        else    { --i; }                                                }

                else if(x> 32 && x <= 34)       { if( ((pozycja = opis2.std::string::find("włosy")) == std::string::npos )     &&
                                                                                  ((pozycja = opis2.std::string::find("łysy")) == std::string::npos )  &&
                                                                                  ( plec != "K" )                                                                                                               &&
                                                                                  ((pozycja = opis2.std::string::find("łysiejący")) == std::string::npos )    )
                                                                        { opis2 += "łysy";
                                                                        wlosy.std::string::clear();
                                                                        wlosy = "brak";                                                 }
                                                                        else    { --i; }                                                }

                else if(x> 34 && x <= 36)       { if( ((pozycja = opis2.std::string::find("łysy")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("łysiejący")) == std::string::npos )    &&
                                                                                  ((pozycja = opis2.std::string::find("dł.włosy")) == std::string::npos )     &&
                                                                                  ((pozycja = opis2.std::string::find("wypadające")) == std::string::npos )    )
                                                                        { opis2 += "bardzo dł.włosy";                 }
                                                                        else    { --i; }                                                }

                else if(x> 36 && x <= 38)       { if( ((pozycja = opis2.std::string::find("sarnie")) == std::string::npos )             &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos ) )
                                                                        { opis2 += "sarnie oczy";                               }
                                                                        else    { --i; }                                                }

                else if(x> 38 && x <= 40)       { if( ((pozycja = opis2.std::string::find("łysy")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("kręcone włosy")) == std::string::npos ) )
                                                                        { opis2 += "kręcone włosy";                           }
                                                                        else    { --i; }                                                }

                else if(x> 40 && x <= 42)       { if( ((pozycja = opis2.std::string::find("łysy")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("wypadające włosy")) == std::string::npos ) )
                                                                        { opis2 += "wypadające włosy";                        }
                                                                        else    { --i; }                                                }

                else if(x> 42 && x <= 44)       { if( ((pozycja = opis2.std::string::find("mądre")) == std::string::npos )             &&
                                                                                  ((pozycja = opis2.std::string::find("mruganie")) == std::string::npos )       &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos ) )
                                                                        { opis2 += "mądre oczy";                               }
                                                                        else    { --i; }                                                }

                else if(x> 44 && x <= 46)       { if( ((pozycja = opis2.std::string::find("łysy")) == std::string::npos )              &&
                                                                                  ( plec != "K" )                                                                                                                       &&
                                                                                  ((pozycja = opis2.std::string::find("łysiejący")) == std::string::npos ) )
                                                                        { opis2 += "łysiejący";                                       }
                                                                        else    { --i; }                                                }

                else if(x> 46 && x <= 48)       { if( (pozycja = opis2.std::string::find("garbienie")) == std::string::npos )
                                                                        { opis2 += "garbienie się";                            }
                                                                        else    { --i; }                                                }
       
                else if(x> 48 && x <= 50)       { if( (pozycja = opis2.std::string::find("kurza kl.")) == std::string::npos )
                                                                        { opis2 += "kurza kl.piersiowa";                }
                                                                        else    { --i; }                                                }

                else if(x> 50 && x <= 52)       { if( ((pozycja = opis2.std::string::find("smutna twarz")) == std::string::npos )       &&
                                                                                  ((pozycja = opis2.std::string::find("przyjazny")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("zadowolony")) == std::string::npos )             &&
                                                                                  ((pozycja = opis2.std::string::find("radosny")) == std::string::npos )        )
                                                                        { opis2 += "smutna twarz";                              }
                                                                        else    { --i; }                                                }

                else if(x> 52 && x <= 54)       { if( (pozycja = opis2.std::string::find("odstające uszy")) == std::string::npos )
                                                                        { opis2 += "odstające uszy";                   }
                                                                        else    { --i; }                                                }

                else if(x> 54 && x <= 56)       { if( ((pozycja = opis2.std::string::find("pulchna warga")) == std::string::npos )      &&
                                                                                  ((pozycja = opis2.std::string::find("wąskie usta")) == std::string::npos )   )
                                                                        { opis2 += "pulchna warga";                             }
                                                                        else    { --i; }                                                }

                else if(x> 56 && x <= 58)       { if( ((pozycja = opis2.std::string::find("surowa twarz")) == std::string::npos )       &&
                                                                                  ((pozycja = opis2.std::string::find("sarnie")) == std::string::npos )                 &&
                                                                                  ((pozycja = opis2.std::string::find("ciepłe")) == std::string::npos )                        &&
                                                                                  ((pozycja = opis2.std::string::find("radosny")) == std::string::npos )                &&
                                                                                  ((pozycja = opis2.std::string::find("zadowolony")) == std::string::npos )             &&
                                                                                  ((pozycja = opis2.std::string::find("przyjazny")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("charyzmat.")) == std::string::npos )             &&
                                                                                  ((pozycja = opis2.std::string::find("dobrotliwy")) == std::string::npos )     )
                                                                        { opis2 += "surowa twarz";                              }
                                                                        else    { --i; }                                                }

                else if(x> 58 && x <= 60)       { if( ((pozycja = opis2.std::string::find("wklęsłe")) == std::string::npos )          &&
                                                                                  ((pozycja = opis2.std::string::find("piękne oczy")) == std::string::npos )   &&
                                                                                  ((pozycja = opis2.std::string::find("wyłupiaste")) == std::string::npos )    )
                                                                        { opis2 += "wklęsłe oczodoły";                       }
                                                                        else    { --i; }                                                }

                else if(x> 60 && x <= 62)       { if( (pozycja = opis2.std::string::find("blada cera")) == std::string::npos )
                                                                        { opis2 += "bardzo blada cera";                 }
                                                                        else    { --i; }                                                }

                else if(x> 62 && x <= 64)       { if( ((pozycja = opis2.std::string::find("ciepłe")) == std::string::npos )                    &&
                                                                                  ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )                 &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )                       &&
                                                                                  ( charakter != "Zły" )                                                                                                               &&
                                                                                  ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )        )
                                                                        { opis2 += "ciepłe spojrzenie";                        }
                                                                        else    { --i; }                                                }

                else if(x> 64 && x <= 66)       { if( ((pozycja = opis2.std::string::find("z bliznami")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("przyjazny")) == std::string::npos )              &&
                                                                                  ((pozycja = opis2.std::string::find("atrakcyjna")) == std::string::npos )     )
                                                                        { opis2 += "cera z bliznami";                   }
                                                                        else    { --i; }                                                }

                else if(x> 66 && x <= 68)       { if( ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )           &&
                                                                                  ((pozycja = opis2.std::string::find("sarnie")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("ciepłe")) == std::string::npos )                &&
                                                                                  ((pozycja = opis2.std::string::find("piękne")) == std::string::npos )                &&
                                                                                  ((pozycja = opis2.std::string::find("atrakcyjna")) == std::string::npos )     &&
                                                                                  ((pozycja = opis2.std::string::find("mądre")) == std::string::npos ) )
                                                                        { opis2 += "błędny wzrok";                            }
                                                                        else    { --i; }                                                }

                else if(x> 68 && x <= 70)       { if( ((pozycja = opis2.std::string::find("dobrotliwy")) == std::string::npos ) &&
                                                                                  ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )               &&
                                                                                  ( charakter != "Zły" )                                                                                                       &&
                                                                                  ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )        )
                                                                        { opis2 += "dobrotliwy wyr.twarzy";             }
                                                                        else    { --i; }                                                }

                else if(x> 70 && x <= 72)       { if( (pozycja = opis2.std::string::find("szeroka twarz")) == std::string::npos )
                                                                        { opis2 += "szeroka twarz";                             }
                                                                        else    { --i; }                                                }

                else if(x> 72 && x <= 74)       { if( ((pozycja = opis2.std::string::find("niekompletne")) == std::string::npos )       &&
                                                                                  ((pozycja = opis2.std::string::find("białe zęby")) == std::string::npos )           &&
                                                                                  ((pozycja = opis2.std::string::find("atrakcyjna")) == std::string::npos )     )
                                                                        { opis2 += "niekompletne uzębienie";   }
                                                                        else    { --i; }                                                }

                else if(x> 74 && x <= 76)       { if( ((pozycja = opis2.std::string::find("wąskie usta")) == std::string::npos )       &&
                                                                          ((pozycja = opis2.std::string::find("pulchna")) == std::string::npos )        )
                                                                        { opis2 += "wąskie usta";                              }
                                                                        else    { --i; }                                                }

                else if(x> 76 && x <= 78)       { if( (pozycja = opis2.std::string::find("białe zęby")) == std::string::npos )
                                                                        { opis2 += "białe zęby";                              }
                                                                        else    { --i; }                                                }

                else if(x> 78 && x <= 80)       { if( ((pozycja = opis2.std::string::find("seplenienie")) == std::string::npos )                &&
                                                                                  ((pozycja = opis2.std::string::find("czysty głos")) == std::string::npos )           &&
                                                                                  ((pozycja = opis2.std::string::find("niewyraźna")) == std::string::npos )    )
                                                                        { opis2 += "seplenienie";                               }
                                                                        else    { --i; }                                                }

                else if(x> 80 && x <= 82)       { if( ((pozycja = opis2.std::string::find("radosny")) == std::string::npos )    &&
                                                                                  ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )               &&
                                                                                  ( charakter != "Zły" )                                                                                                       &&
                                                                                  ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )        )
                                                                        { opis2 += "radosny wyr.twarzy";                }
                                                                        else    { --i; }                                                }

                else if(x> 82 && x <= 84)       { if( ((pozycja = opis2.std::string::find("tik nerwowy")) == std::string::npos )        &&
                                                                          ((pozycja = opis2.std::string::find("przyjazny")) == std::string::npos )      &&
                                                                          ((pozycja = opis2.std::string::find("sarnie")) == std::string::npos )         &&
                                                                          ((pozycja = opis2.std::string::find("ciepłe")) == std::string::npos )                &&
                                                                          ((pozycja = opis2.std::string::find("radosny")) == std::string::npos )        )
                                                                        { opis2 += "tik nerwowy ust";                   }
                                                                        else    { --i; }                                                }

                else if(x> 84 && x <= 86)       { if( ((pozycja = opis2.std::string::find("seplenienie")) == std::string::npos )        &&
                                                                          ((pozycja = opis2.std::string::find("szybka")) == std::string::npos )         &&
                                                                          ((pozycja = opis2.std::string::find("niewyraźna")) == std::string::npos )    )
                                                                        { opis2 += "czysty głos";                              }
                                                                        else    { --i; }                                                }

                else if(x> 86 && x <= 88)       { if( (pozycja = opis2.std::string::find("zadarty")) == std::string::npos )
                                                                        { opis2 += "zadarty nos";                               }
                                                                        else    { --i; }                                                }

                else if(x> 88 && x <= 89)       { if( ((pozycja = opis2.std::string::find("niewyraźna")) == std::string::npos )        &&
                                                                          ((pozycja = opis2.std::string::find("czysty")) == std::string::npos ) )
                                                                        { opis2 += "niewyraźna mowa";                  }
                                                                        else    { --i; }                                                }

                else if(x> 89 && x <= 90)       { if( ((pozycja = opis2.std::string::find("czysty")) == std::string::npos )             &&
                                                                              ((pozycja = opis2.std::string::find("szybka")) == std::string::npos )     )
                                                                        { opis2 += "szybka mowa";                               }
                                                                        else    { --i; }                                                }

                else if(x> 90 && x <= 91)       { if( ((pozycja = opis2.std::string::find("piękne oczy")) == std::string::npos )       &&
                                                                                  ((pozycja = opis2.std::string::find("oko mniejsze")) == std::string::npos )&&
                                                                                  ((pozycja = opis2.std::string::find("wyłupiaste")) == std::string::npos )    )
                                                                        { opis2 += "piękne oczy";                              }
                                                                        else    { --i; }                                                }

                else if(x> 91 && x <= 92)       { if( (pozycja = opis2.std::string::find("krzaczaste")) == std::string::npos )
                                                                        { opis2 += "krzaczaste brwi";                   }
                                                                        else    { --i; }                                                }

                else if(x> 92 && x <= 93)       { if( ((pozycja = opis2.std::string::find("duże uszy")) == std::string::npos ) &&
                                                                                  ((pozycja = opis2.std::string::find("pokaźne")) == std::string::npos )       )
                                                                        { opis2 += "duże uszy";                                        }
                                                                        else    { --i; }                                                }

                else if(x> 93 && x <= 94)       { if( ((pozycja = opis2.std::string::find("przyjazny")) == std::string::npos )  &&
                                                                                  ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )               &&
                                                                                  ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )        )
                                                                        { opis2 += "przyjazny wyr.twarzy";              }
                                                                        else    { --i; }                                                }

                else if(x> 94 && x <= 95)       { if( ((pozycja = opis2.std::string::find("wąsy")) == std::string::npos )              &&
                                                                          ( plec != "K" )       /*Kobieta nie ma wąsów*/                                              )
                                                                        { opis2 += "wąsy";                                             }
                                                                        else    { --i; }                                                }

                else if(x> 95 && x <= 96)       { if( ((pozycja = opis2.std::string::find("wyłupiaste")) == std::string::npos )        &&
                                                                                ((pozycja = opis2.std::string::find("sarnie")) == std::string::npos )           &&
                                                                                ((pozycja = opis2.std::string::find("piękne")) == std::string::npos )          &&
                                                                                ((pozycja = opis2.std::string::find("atrakcyjna")) == std::string::npos )       &&
                                                                                ((pozycja = opis2.std::string::find("mądre")) == std::string::npos )   )
                                                                        { opis2 += "wyłupiaste oczy";                  }
                                                                        else    { --i; }                                                }

                else if(x> 96 && x <= 97)       { if( ((pozycja = opis2.std::string::find("zadowolony")) == std::string::npos ) &&
                                                                                  ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )         &&
                                                                                  ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )               &&
                                                                                  ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )        )
                                                                        { opis2 += "zadowolony wyr.twarzy";             }
                                                                        else    { --i; }                                                }

                else if(x> 97 && x <= 98)       { if( ((pozycja = opis2.std::string::find("owłosione uszy")) == std::string::npos ) &&
                                                                          ( plec != "K" ) )
                                                                        { opis2 += "owłosione uszy";                   }
                                                                        else    { --i; }                                                }

                else if(x> 98 && x <= 99)       { if( (pozycja = opis2.std::string::find("żylaste")) == std::string::npos )
                                                                        { opis2 += "żylaste ręce";                            }
                                                                        else    { --i; }                                                }

                else if(x> 99)                          { if( (pozycja = opis2.std::string::find("paznokcie")) == std::string::npos )
                                                                        { opis2 += "długie paznokcie";                 }
                                                                        else    { --i; }                                                }

                opis2 += ", ";
        }
        //przepisuję wylosowane cechy z tymczasowego obiektu "opis2" do prywatnego składnika klasy - "opis",
        //usuwając przy tym przecinek na końcu stringu.
        if( (pozycja = opis2.std::string::rfind(",")) != std::string::npos ) //usuwanie ostatniego przecinka
        { opis2.std::string::erase(pozycja, 1); }
        opis = opis2;
}
 

Widzę, że tabulatory w kodzie się poprzestawiały i wygląda mniej przejrzyście. Przepraszam za to, ustawiałem je w notepad++ i tam wygląda pięknie.

Jak wspomniałem w komentarzach w kodzie, pętla for(), która obraca się tyle razy ile wcześniej wylosuje się cech, czasem wariuje i mieli w nieskończoność.
Na początku myślałem, że może powoduje to else { --i; } ale warunek w pętli domknąłem tak: for(int i=0; (i>=0 && i<y); i++).
Po tej modyfikacji nadal się tak samo dzieje. Następnie podejrzewałem, że w warunkach typu:
KOD cpp:     UKRYJ  
if( ((pozycja = opis2.std::string::find("zadowolony")) == std::string::npos )   &&
    ((pozycja = opis2.std::string::find("surowa")) == std::string::npos )               &&
    ((pozycja = opis2.std::string::find("błędny")) == std::string::npos )             &&
   ((pozycja = opis2.std::string::find("gniewne")) == std::string::npos )       )
 

obiekt "pozycja" nie powinien być taki sam tylko na przykład: pozycja1, pozycja2, pozycja3...i tak dalej. Dodałem więc tych zmiennych i przerobiłem tak kod ale bez pozytywnych rezultatów. Najgorsze jest to, że gdy ustawię na tej funkcji breakpoint aby wskoczyć do nie i uruchamiać ją linijka po linijce to wszystko pyka pięknie! Lecz gdy uruchamiam ją normalnie to raz na jakiś czas się zapętla i tym samym zawiesza. Nie widzę przyczyny :cry:
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez polymorphism » piątek, 23 lutego 2018, 11:35

Łooo matko! :shock: Funkcja, która ma pół tysiąca linii to proszenie się o problemy. Zrefaktoryzuj ją.

KOD cpp:     UKRYJ  
if ((pozycja = opis2.std::string::find("duży nos")) == std::string::npos)

Po co to std::string::?

KOD cpp:     UKRYJ  
for (int i = 0; i < y; i++) //<----- ta pętla czasem obraca się w nieskończoność

Wystarczy, że wylosujesz obok siebie dwie liczby z jednego przedziału i pętla będzie się kręcić w miejscu. Według mnie ta pętla nie jest do końca przemyślana. Po co te przedziały? Nie lepiej po prostu wylosować liczby z mniejszego zakresu?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2164
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 199
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez Arnold_S » piątek, 23 lutego 2018, 14:39

Ja wiem, że kod zrobiony jest "na piechotę" ale chciałem żeby było to dokładnie odwzorowane od podręcznika do tej gry i zasad które tam panują.
Jet to gra fabularna - książkowa (nie komputerowa).
Cechy, które widzisz i przedziały liczb im odpowiadające są zerżnięte z podręcznika. Poprostu w realnym świecie bierzesz do ręki kości K100 (wynik od 1 do 100) i to co wyjdzie porównujesz z tabelką w podręczniku. Dodatkowo muszę pilnować aby kobieta nie wylosowała wąsów lub owłosionych uszu :)
Stąd tyle warunków i ta wielka tabelka. Zdaję sobie sprawę, że nie wygląda to elegancko ale działa według receptury podręcznika.

Ad1. na początku w klasie użyć: using namespace std; ? i w reszcie kodu klasy nie używać std::string:: ?

Ad2. kurcze w jakich przypadkach może się zawirować ta pętla? Zmienna y może przyjmować tylko liczby 1,2,3 - nic innego. Kurcze mam jakiegoś zeza wyobraźni...


/edit
Napisałeś, że tak długa funkcja prosi się o problem. Jakie niesie za sobą konsekwencje tworzenie takich długich funkcji?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez polymorphism » piątek, 23 lutego 2018, 20:37

na początku w klasie użyć: using namespace std; ? i w reszcie kodu klasy nie używać std::string:: ?

We fragmencie, który zacytowałem, std::string:: jest kompletnie niepotrzebne. Wystarczy:
KOD cpp:     UKRYJ  
if ((pozycja = opis2.find("duży nos")) == std::string::npos)


kurcze w jakich przypadkach może się zawirować ta pętla?

KOD cpp:     UKRYJ  
for(int i = 0; i < y; i++)
{
        x = ostatnio[i];

        if(x <= 2 )
        {
                if( (pozycja = opis2.std::string::find("duży nos")) == std::string::npos )
                {
                        opis2 += "duży nos";
                }
                else
                {
                        --i;
                }
                ...

Załóż, że w ostatnio są wylosowane wartości 1, 2, ...; Pierwszy obrót dodaje opis, drugi - nie dodaje, bo już jest, więc cofa i o jeden, następny - i wskazuje na 2, więc znowu nic nie dodaje i oczywiście cofa i o jeden. I tak w kółko. Program zawiesza się wtedy, gdy obok siebie wylosowane zostaną liczby z jednego przedziału. Stąd ta nieregularność zwieszek.

Jakie niesie za sobą konsekwencje tworzenie takich długich funkcji?

Ten wątek jest jedną z tych konsekwencji - nie widzisz błędu, bo ciężko się taką funkcję analizuje.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2164
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 199
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez Arnold_S » piątek, 23 lutego 2018, 22:56

Kurcze masz rację! Patrzyłem na tą pętlę setki razy i wydawało mi się wszystko okej.
Wydaje mi się jednak, że nie jest to główny problem. Pokusiło mnie i dopisałem parę "cout-ów", które w pętli wypisują na ekran stan kilku zmiennych. Chciałem sprawdzić co takiego siedzi w tablicy ostatnio[].
I tak na przykład, przy kilku próbach, pętla osiągała nieskończoność z takimi parametrami:

x=69, y=3, i=1, ostatnio [58,69,91]
x=69, y=3, i=2, ostatnio [80,93,69]
x=5, y=3, i=1, ostatnio [ 6, 5,93] <--- tutaj są z jednego przedziału
x=57, y=3, i=2, ostatnio [18,69,57]
x=70, y=2, i=1, ostatnio [92,70, 0]
x=91, y=3, i=2, ostatnio [14,98,91] <--- tutaj są z jednego przedziału
x=23, y=2, i=1, ostatnio [29,23, 0]
x=69, y=3, i=2, ostatnio [54,89,69]
x=63, y=1, i=0, ostatnio [63, 0, 0]
x=10, y=3, i=2, ostatnio [ 9,51,10] <--- tutaj są z jednego przedziału
x=68, y=2, i=1, ostatnio [67,68, 0] <--- tutaj są z jednego przedziału
x=58, y=2, i=1, ostatnio [82,58, 0]
x=81, y=2, i=0, ostatnio [81,20, 0]

Jak widać tylko w 4 miejscach na 13 razy, liczby w tablicy ostatnio, były z tego samego przedziału.
Następnie zrobiłem taki test, że ręcznie (bez losowania) wprowadziłem tylko jedną kolejkę pętli i odpowiednio wypełniłem tablicę ostatnio:
x=63, y=1, ostatnio[63,0,0]
W takim przypadku też się zapętla :( mimo, że jest tylko jedna cecha. Co ciekawe, gdy wykonuję kod "krok po kroku" (linijka po linijce), to program się nie zapętla i wszystko przechodzi dalej, a gdy odpalam bez debagowania to różnie to bywa...
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez polymorphism » sobota, 24 lutego 2018, 11:48

Wydaje mi się jednak, że nie jest to główny problem.

To jest główny problem, choć może nie jedyny, bo:
odpowiednio wypełniłem tablicę ostatnio:
x=63, y=1, ostatnio[63,0,0]
W takim przypadku też się zapętla

KOD cpp:     UKRYJ  
else if (x > 62 && x <= 64)
{
        if (((pozycja = opis2.find("ciepłe")) == std::string::npos) &&
                ((pozycja = opis2.find("surowa")) == std::string::npos) &&
                ((pozycja = opis2.find("błędny")) == std::string::npos) &&
                (charakter != "Zły") &&        // <--- !!!
                ((pozycja = opis2.find("gniewne")) == std::string::npos))
        {
                ...
        }
        else
        {
                --i;
        }
}

Wystarczy, że charakter będzie "Zły" i masz never ending pętlę ;) W sumie sytuacja podobna do błędu, który wcześniej wskazałem.

Nie rozumiem, dlaczego uparłeś się, żeby najpierw wylosować trzy wartości losowe, jeśli wiesz, że pewne wartości-cechy mogą się wykluczać lub powtarzać. To jest powód twoich problemów. Losowanie powinno odbywać się w głównej pętli i jeśli jakaś cecha się wyklucza lub powtarza, losujesz tak długo, aż trafisz w cechę, którą możesz dodać.

I jeszcze raz: r e f a k t o r y z a c j a!

PS. po co te "pozycja =" w warunkach? Przecież nigdzie nie wykorzystujesz tej zmiennej.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Arnold_S
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2164
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 199
System operacyjny: Windows 7 Pro
Windows 8.1
Linux Mint 19
Kompilator: Visual Studio 2015 Community
CodeLite (MinGW)
MSYS2 (MinGW, clang)
g++
Gadu Gadu: 0
    Windows 7Firefox

Re: Niezidentyfikowany błąd (praca z klasami)

Nowy postprzez Arnold_S » sobota, 24 lutego 2018, 12:07

Masz rację. Trzeba to napisać od nowa i krócej :)

Z tą zmienną "pozycja" to jakoś mnie olśniło, że trzeba najpierw przypisać to co zwraca funkcja find(), a potem to porównać :lol:
No faktycznie, że wystarczy porównać z wartością zwracaną...i bez przypisania.
Poprawię te błędy przy konstruowaniu funkcji od nowa.
Następnie popatrzę o co chodzi z tym drugim błędem, który zawiesza program. Jeśli nie dam rady to znowu poproszę o pomoc.
Wielkie dzięki!! Jak zwykle można liczyć na Ciebie!

8-) 8-) 8-)
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Google [Bot] i 0 gości

cron