Chciałem zapytać, czy możliwe są wycieki pamięci gdy nie używamy ani malloca, ani new .... Tworzę tablicę char tab[1000]. wskaźnik do tablicy (tab) przekazuje do funkcji, która przekazuje ją do jeszcze innej funkcji. Po drodze nic z nim specjalnego nie robie - odczytuje, kopiuje itp.
Korzystam ze klas string, vector, map ...
Valgrind pokazuje, że mam wycieki pamięci.
==7664== 9,445 (964 direct, 8,481 indirect) bytes in 1 blocks are definitely lost in loss record 22 of 27
==7664== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==7664== by 0x407A40E: my_malloc (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x40A64EB: mysql_init (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x804BCD1: user_mysql_authorization(mysql_log_data_struct const&, std::string const&, std::string const&, bool&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, bool) (main.cpp:562)
==7664== by 0x804C79C: getuserinfo_command(mysql_log_data_struct const&, cmd_t const&, std::string const&, std::string&, bool&) (main.cpp:702)
==7664== by 0x804A784: thread_proc(void*) (main.cpp:279)
==7664== by 0x435ECC8: start_thread (pthread_create.c:304)
==7664== by 0x444369D: clone (clone.S:130)
==7664== 28,616 bytes in 7 blocks are possibly lost in loss record 27 of 27
==7664== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==7664== by 0x408253D: my_once_alloc (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x4082D99: ??? (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x4083889: ??? (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x4083ADB: get_charset_by_csname (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x40A6211: mysql_init_character_set (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x40A82DB: mysql_real_connect (in /usr/lib/libmysqlclient.so.16.0.0)
==7664== by 0x804BD4C: user_mysql_authorization(mysql_log_data_struct const&, std::string const&, std::string const&, bool&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, std::string&, bool) (main.cpp:566)
==7664== by 0x804D258: join_command(mysql_log_data_struct const&, cmd_t const&, std::string&, bool&) (main.cpp:773)
==7664== by 0x804A4A3: thread_proc(void*) (main.cpp:237)
==7664== by 0x435ECC8: start_thread (pthread_create.c:304)
==7664== by 0x444369D: clone (clone.S:130)
Wiem, że słabo opisałem problem, ale nie wiem za bardzo co wkleić. Dla przykładu mogę wkleić funkcję join ...
int join_command(const mysql_log_data_struct &mysql_log_data, const cmd_t &cmd, string &msg, bool &isAdmin)
{
int retval = 0;
map<string, client_t>::iterator client_iter;
map<string, clientAdmin_t>::iterator admin_iter;
string nieprzeczytane = "";
clientAdmin_t klientTemp;
klientTemp.pin = cmd.op1;
if(cmd.op1.length() == 0 || cmd.op2.length() == 0)
{
msg = "201 INVALID ID / PIN";
retval = 0;
}
else
{
if(user_mysql_authorization(mysql_log_data, cmd.op1, cmd.op2, isAdmin, klientTemp.imie, klientTemp.nazwisko,
klientTemp.miejscowosc, klientTemp.ulica, klientTemp.nr,
klientTemp.stanowisko, klientTemp.status, nieprzeczytane) == true)
{
if(isAdmin == false) //Zwykły klient.
{
//Czy nick jest już na liście ?
pthread_mutex_lock(&client_list_mutex);
client_iter = client_list.find(cmd.op1);
if(client_iter == client_list.end()) //nie ma na liście
{
//dodajemy klienta do listy
client_list[cmd.op1].pin = cmd.op1;
client_list[cmd.op1].imie = klientTemp.imie;
client_list[cmd.op1].nazwisko = klientTemp.nazwisko;
client_list[cmd.op1].miejscowosc = klientTemp.miejscowosc;
client_list[cmd.op1].ulica = klientTemp.ulica;
client_list[cmd.op1].nr = klientTemp.nr;
//zapis daty logowania ...
user_mysql_log_date(mysql_log_data, cmd.op1);
//wysyłamy dane do świeżo zalogowanego usera ...
client_list[cmd.op1].wychodzace.push_back(make_info_command(klientTemp, "MYINFO"));
//powiadamiamy adminów o przyłączeniu się usera i wysyłamy info o nim
client_list[cmd.op1].wychodzace.push_back("UNREAD " + (string)nieprzeczytane);
pthread_mutex_lock(&admin_list_mutex);
for (admin_iter = admin_list.begin() ; admin_iter != admin_list.end(); ++admin_iter)
{
//każdy admin dostaje info o przyłączeniu się nowego usera.
//(*admin_iter).second.wychodzace.push_back("JOINUSER " + cmd.op1);
//i wszelkie informacje o nim samym - imie, nazwisko itd;
(*admin_iter).second.wychodzace.push_back(make_info_command(klientTemp, "JOINUSER"));
//wysyłamy userowi dane na temat każdego z adminów ...
if((*admin_iter).second.status == "hide" || (*admin_iter).second.status == "userhide") continue;
client_list[cmd.op1].wychodzace.push_back(make_info_command( (*admin_iter).second , "ADMININFO"));
}
pthread_mutex_unlock(&admin_list_mutex);
msg = "100 OK";
retval = 1;
}
else //jest na liście
{
msg = "200 PIN ALREADY IN USE";
retval = 0;
}
pthread_mutex_unlock(&client_list_mutex);
}
else //admin...
{
pthread_mutex_lock(&admin_list_mutex);
admin_iter = admin_list.find(cmd.op1);
if(admin_iter == admin_list.end()) //takiego admina nie ma na liście
{
//dodajemy admina do listy
admin_list[cmd.op1].pin = cmd.op1;
admin_list[cmd.op1].imie = klientTemp.imie;
admin_list[cmd.op1].nazwisko = klientTemp.nazwisko;
admin_list[cmd.op1].miejscowosc = klientTemp.miejscowosc;
admin_list[cmd.op1].ulica = klientTemp.ulica;
admin_list[cmd.op1].nr = klientTemp.nr;
admin_list[cmd.op1].stanowisko = klientTemp.stanowisko;
admin_list[cmd.op1].status = klientTemp.status;
user_mysql_log_date(mysql_log_data, cmd.op1);
for (admin_iter = admin_list.begin() ; admin_iter != admin_list.end(); ++admin_iter)
{
if((*admin_iter).first == cmd.op1)
{
//wysyłamy świeżo zalogowanemy adminowi info o sobie ...
(*admin_iter).second.wychodzace.push_back(make_info_command(klientTemp, "MYADMININFO"));
//wysłanie liczby nieprzeczytanych wiadomości zostawionych na serwerze ...
(*admin_iter).second.wychodzace.push_back("UNREAD " + nieprzeczytane);
continue;
}
//każdy admin dostaje info o przyłączeniu się nowego admina, jeśli ten nie jest ukryty ...
if(admin_list[cmd.op1].status != "hide")
(*admin_iter).second.wychodzace.push_back(make_info_command(klientTemp, "ADMININFO"));
if( (*admin_iter).second.status == "hide" ) continue;
//nowy admin dostaje info o dostępnych(zalogowanych) adminach ...
admin_list[cmd.op1].wychodzace.push_back( make_info_command((*admin_iter).second, "ADMININFO" ));
}
pthread_mutex_lock(&client_list_mutex); //informowanie userów o nowym adminie ...
for (client_iter = client_list.begin() ; client_iter != client_list.end() ; ++client_iter)
{
//każdy user dostaje info o dostępności admina ( zaświeci się np. sprawy techniczne ).
//(*client_iter).second.wychodzace.push_back("JOINADMIN " + cmd.op1);
admin_list[cmd.op1].wychodzace.push_back( make_info_command(reinterpret_cast<clientAdmin_t &>((*client_iter).second), "JOINUSER" ));
if(klientTemp.status == "hide" || klientTemp.status == "userhide") continue;
(*client_iter).second.wychodzace.push_back(make_info_command(klientTemp, "ADMININFO"));
}
pthread_mutex_unlock(&client_list_mutex);
msg = "100 OK";
retval = 1;
}
else
{
msg = "200 PIN ALREADY IN USE";
retval = 0;
}
pthread_mutex_unlock(&admin_list_mutex);
}
}
else
{
msg = "300 ERROR_MYSQL_AUTH";
retval = 0; //blad w funkcji user_mysql_authorization.
}
}
return retval;
}
Mniej więcej cała aplikacja wygląda w podobny sposób jak funkcja powyżej... Być może gdzieś popełniam jakiś prosty błąd ?