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

Niezidentyfikowany błąd (praca z klasami)

Nowy postNapisane: środa, 21 lutego 2018, 20:50
przez Arnold_S
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.

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

Nowy postNapisane: czwartek, 22 lutego 2018, 11:20
przez polymorphism
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.

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

Nowy postNapisane: czwartek, 22 lutego 2018, 19:16
przez Arnold_S
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:

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

Nowy postNapisane: piątek, 23 lutego 2018, 11:35
przez polymorphism
Ł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?

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

Nowy postNapisane: piątek, 23 lutego 2018, 14:39
przez Arnold_S
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?

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

Nowy postNapisane: piątek, 23 lutego 2018, 20:37
przez polymorphism
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.

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

Nowy postNapisane: piątek, 23 lutego 2018, 22:56
przez Arnold_S
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...

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

Nowy postNapisane: sobota, 24 lutego 2018, 11:48
przez polymorphism
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.

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

Nowy postNapisane: sobota, 24 lutego 2018, 12:07
przez Arnold_S
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-)