2012-07-16 24 views
0

我正在對此函數進行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來清理這個問題,這是推薦的方法。

但爲什麼我在這裏得到段錯誤。我用valgrind跑了它。輸出和相應的代碼可以發現here

回答

3

g_strdupv()副本一個NULL C末尾終止數組(每個都必須以NUL終止)。 C API Data Structures上的MySQL文檔指出MYSQL_ROW是一個字節串的數組,如果字段值可能包含二進制數據,則這些字節串不一定是NUL終止的。因此MYSQL_ROW既不能保證是一個NULL-終止數組也不是一個C字符串數組。

段錯誤很可能是因爲g_strdupv()一直在尋找NULL終止符,但直到它嘗試讀取非進程內存時才找到它。

+0

我的查詢是'用戶的SELECT'ID,其中nick ='shiplu''。它只返回'22'。你是說22不是以空結尾? – 2012-07-16 13:32:57

+0

@ shiplu.mokadd.im:一個字節的字符串可能以NUL結尾,但字符串數組「行」不是以NULL結尾的。 – 2012-07-16 13:36:19

+0

我想我必須使用[mysql_fetch_lengths](http://dev.mysql.com/doc/refman/5.1/en/mysql-fetch-lengths.html)。 – 2012-07-16 13:39:19