Я работаю над системой, использующей множество запросов MySQL, и я сталкиваюсь с некоторыми проблемами памяти. Я почти уверен, что мне приходится обращаться с неправильным указателем...
В принципе, у меня есть что-то вроде этого:
MYSQL_ROW function1() {
string query="SELECT * FROM table limit 1;";
MYSQL_ROW return_row;
mysql_init(&connection); // "connection" is a global variable
if (mysql_real_connect(&connection,HOST,USER,PASS,DB,0,NULL,0)){
if (mysql_query(&connection,query.c_str()))
cout << "Error: " << mysql_error(&connection);
else{
resp = mysql_store_result(&connection); //"resp" is also global
if (resp) return_row = mysql_fetch_row(resp);
mysql_free_result(resp);
}
mysql_close(&connection);
}else{
cout << "connection failed\n";
if (mysql_errno(&connection))
cout << "Error: " << mysql_errno(&connection) << " " << mysql_error(&connection);
}
return return_row;
}
И function2()
:
MYSQL_ROW function2(MYSQL_ROW row) {
string query = "select * from table2 where code = '" + string(row[2]) + "'";
MYSQL_ROW retorno;
mysql_init(&connection);
if (mysql_real_connect(&connection,HOST,USER,PASS,DB,0,NULL,0)){
if (mysql_query(&connection,query.c_str()))
cout << "Error: " << mysql_error(&conexao);
else{
// My "debugging" shows me at this point `row[2]` is already fubar
resp = mysql_store_result(&connection);
if (resp) return_row = mysql_fetch_row(resp);
mysql_free_result(resp);
}
mysql_close(&connection);
}else{
cout << "connection failed\n";
if (mysql_errno(&connection))
cout << "Error : " << mysql_errno(&connection) << " " << mysql_error(&connection);
}
return return_row;
}
И main()
представляет собой бесконечный цикл в основном так:
int main( int argc, char* args[] ){
MYSQL_ROW row = NULL;
while (1) {
row = function1();
if(row != NULL) function2(row);
}
}
(имена переменных и функций были обобщены для защиты невинных)
Но после третьего или четвертого вызова function2
, который использует только row
для чтения, row
начинает терять свое значение, приходящее на ошибку segfault...
У кого-нибудь есть идеи? Я не уверен, что количество глобальных переменных в этом коде какое-то хорошее, но я его не проектировал и только до завтра исправил и закончил, поэтому обходные решения приветствуются!
Спасибо!
Обновление: я неправильно понял, как используются результаты mysql. Похоже, что указательный массив row
указывает на массив результатов, который вы производите в function1()
, а затем используйте его в function2()
после того, как он был возвращен в кучу.
Что вам нужно сделать, это скопировать return_row[2]
в постоянную строку перед освобождением результатов. Затем переходим к function2()
. Я вижу, что вы делаете что-то подобное в function2()
, поэтому вам также нужно исправить его (хотя в вашем примере вы ничего не делаете с его возвращаемым значением).
Кроме того, вы правы, что free(row);
- это не то, что нужно делать.
Вы не должны закрывать соединение или освобождать набор результатов во время обработки строки, возвращаемой mysql_fetch_row.