Prośba o sprawdzenie gdzie kryją się błędy

0

Witam,
Nie jestem bardzo dobrym programistą, ale jakoś sobie radzę.
Pewna osoba poprosiła mnie abym stworzył bibliotekę do obsługi protokołu Gadu-Gadu, więc zacząłem ją robić myśląc, że będzie to dobre doświadczenie i czegoś się przy okazji nauczę.

Napisałem już logowanie się, wysyłanie listy kontaktów, powiadomienia o zmianie stanu kontaktów z listy, odbieranie wiadomości, wysyłanie wiadomości, zmianę statusu.
Niby to wszystko działa, ale bardzo niestabilnie. I o to właśnie chodzi, żeby ktoś dobroduszny z kawałkiem wolnego czasu zerknął w kod i powiedział co poprawić by uzyskać stabilność. Teraz jest tak, że w 9 na 10 przypadków wszystko zadziała, a w tym jednym przypadku program się wysypie zaraz po uruchomieniu, czasami też kiedy po prostu pochodzi dłużej samo odbieranie (po metodzie startRecvLoop) również się wysypie. W trybie release za każdym razem się wysypuje prawdopodobnie podczas wywołania changeStatus.

Kod jest dostępny tutaj: http://code.google.com/p/egadu/source/browse/#svn%2Ftrunk%2Fsrc

Wiem, że mieć chwilę wolnego czasu w dzisiejszych czasach to rzadkie zjawisko, ale gdyby taki ktoś się znalazł byłbym dozgonnie wdzięczny.
Pozdrawiam.

0

Hm, może dziwne pytanie, ale... skorzystałeś z debuggera?

0

Trochę dziwne :)
Niestety kiedy się tak w losowym momencie wysypuje to debugger pokazuje w którym momencie, ale już po asemblacji, a niestety niby coś tam z asemblera rozumiem, jednak z tego co asembluje kompilator C++ nie zabardzo potrafię się rozczytać.

0

Przejrzałem kod na szybko, jest tragiczny, chociażby to:

char *resolveRetCode(EGADU_RET ret)
{
        string sret;
        switch(ret)
        {
                // przypisania sret
        }

12
        return (char*)sret.c_str();
}

C_str zwraca tymczasowy pointer na zawartość obiektu string, const nie jest tam dla zabawy. Ważniejsze jest jednak, że obiekt sret przestaje istnieć przy wyjściu z funkcji, Ty zaś zwracasz pointer do używanej przez niego pamięci, która już w tym momencie jest zwolniona przez destruktor sret. Kupa podobnych ryzykownych zabaw na pointerach. Wszędzie memleaki, praktycznie nigdzie nie zwalniasz przydzielonej pamięci.

Co do debuggera to i tak pokazuje Ci, w której linii kodu źródłowego, oryginalnego, nastąpił wyjątek. Oczywiście o ile korzystasz z sensownego środowiska/debuggera. Wygląda jakbyś używał VC++, ten zaś ma najlepszy istniejący dla C++ debugger, radzący sobie niemal równie dobrze w trybie release co debug.

0

W sumie to się pośpieszyłem z napisaniem tego wątku.
Jeszcze raz posprawdzałem wszystko i znam już źródło problemu. Jest to metoda resolveHeader, a dokładniej odbieranie pakietów typu GG_USER_DATA. Po zakomentowaniu tego kodu i odbieraniu tych danych po prostu do tablicy nic się nie wysypuje.

A co do tego zwalniania pamięci... od zawsze miałem z tym duży problem. Często wstawiam w nieodpowiednim miejscu delete lub free, a wtedy wszystko się chrzani. Dlatego w mniejszych projektach zostawiam to sobie na koniec, poświęcam trochę czasu i z debuggerem pod ramię staram się trafić w miejsce, w którym ta pamięć nie jest już potrzebna.

0

No, poprawiłem, zwalnianie pamięci dodałem i teraz mogę nawet spamować aplikację pięcioma wiadomościami na sekundę (na więcej mi szybkości w rękach nie starcza) i nic się nie sypie :)

Jeszcze jedno pytanko mam.
Jest tak, że wiadomości, opisy i prawie wszystkie inne ciągi znaków wysyła się w protokole GG w kodowaniu UTF-8. Teraz w mojej bibliotece w metodzie np. zmiany statusu, opis w argumencie jest jako wchar_t. Jest to niby dobre rozwiązanie, bo jeśli zmieni się kodowanie pliku źródłowego na CP1250 lub UTF-8 to polskie znaki fajnie będą działać (wchar_t t = L"ęą"). Ale dla niektórych używanie tego typu może być uciążliwe. Czy jest jakiś sposób, żeby w jedno-bajtowym char zapisać znaki tak jak w dwu-bajtowym wchar_t? W jakim kodowaniu powinien być wtedy plik źródłowy?

0
deus napisał(a)

Przejrzałem kod na szybko, jest tragiczny, chociażby to:

char *resolveRetCode(EGADU_RET ret)
{
        string sret;
        switch(ret)
        {
                // przypisania sret
        }

12
        return (char*)sret.c_str();
}

A przy takim kodzie również występuje bląd?

string resolveRetCode(EGADU_RET ret)
{
        string sret = "asd";

        return set;
}
0

obiekt skopiuje sie i bedzie dzialac dobrze

0

A przy takim kodzie również występuje bląd?

Tak, a konkretnie set: undeclared identifier.

No chyba że set to zmienna globalna.

0

Dodałem skompilowaną wersję biblioteki w wersji release oraz debug.
Gdyby ktoś miał ochotę sprawdzić gdzie jeszcze kryją się błędy/ktoś byłby zainteresowany
https://code.google.com/p/egadu/downloads/list

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