Segfault на функции g_strdupv
Я получаю segfault по этой функции.
/**
* Excutes the passed query and returs the the first row as an array of
* strings. You must free this array by calling g_strfreev()
*/
static gchar** mysql_single_row(MYSQL *mysql_handle, char* query){
my_ulonglong num_rows=0;
MYSQL_RES *result = NULL;
gchar ** single_row = NULL;
GString *q = g_string_new(query);
MYSQL_ROW row={0};
int query_status = mysql_real_query(mysql_handle, q->str, q->len);
if(query_status!=0){
g_string_free(q, TRUE);
return NULL;
}
fprintf(stderr, "Storing mysql result!\n");
result = mysql_store_result(mysql_handle);
if(result==NULL){
/// it was not a query that returns statemnet (e.g. INSERT, DELETE)
g_string_free(q, TRUE);
return NULL;
}
num_rows = mysql_num_rows(result);
fprintf(stderr, "Total rows = %Ld\n", num_rows);
if(num_rows>0){
/// We only fetch the first row
row = mysql_fetch_row(result);
fprintf(stderr, "Copy single rows\n");
single_row = g_strdupv(row); // <------------- SIGSEGV happens here
fprintf(stderr, "Copy single rows done\n");
}else{
mysql_free_result(result);
g_string_free(q, TRUE);
return NULL;
}
/// clean up
g_string_free(q, TRUE);
mysql_free_result(result);
return single_row;
}
По сути, я хочу выполнить запрос SELECT и вернуть первую строку в виде массива строк. Согласно инструкции g_strdupv
следует скопировать возвращенный char **
и делает новый. Я возвращаю это. Позже я уберу это с помощью g_strfreev
который является рекомендуемым методом.
Но почему я получаю сегфо здесь. Я управлял им с Вальгриндом. Выход и соответствующий код можно найти здесь
1 ответ
g_strdupv()
копирует NULL
-определенный массив C-строк (каждая из которых должна заканчиваться NUL). Документация MySQL по структурам данных C API гласит, что MYSQL_ROW
является массивом байтовых строк, которые не обязательно заканчиваются NUL, "если значения полей могут содержать двоичные данные". Таким образом, MYSQL_ROW
ни гарантированно не будет NULL
-определенный массив или массив строк C.
Сегфо, вероятно, происходит потому, что g_strdupv()
продолжает искать NULL
терминатор, но не находит его, пока не попытается выполнить чтение из непроцессной памяти.