2012-07-16 4 views
0

이 함수에서는 segfault가 발생합니다.Segfault on g_strdupv function

/** 
* 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을 사용하여이를 정리합니다.

하지만 왜 내가 여기에 segfaults를 얻고 있습니까? 나는 valgrind와 함께 그것을 달렸다. 출력 및 해당 코드를 찾을 수 있습니다 here

답변

3

g_strdupv()NULL- 끝나는 C 문자열 (각각 NUL 종료되어야 함) 배열을 복사합니다. C API Data Structures의 MySQL 문서에서는 MYSQL_ROW이 "필드 값에 바이너리 데이터가 포함될 수있는 경우"반드시 NUL로 종료되는 것은 아니지만 바이트 문자열 배열임을 명시하고 있습니다. 따라서 MYSQL_ROWNULL- 끝나는 배열이나 C 문자열의 배열이 될 수 없습니다.

g_strdupv()NULL 종결자를 계속 찾고 있기 때문에 segfault가 발생하지만 비 프로세스 메모리 읽기를 시도 할 때까지 찾지 않습니다.

+0

내 검색어는 'nick ='shiplu ''인 사용자의 SELECT ID입니다. '22'만 반환합니다. 22가 null로 종료되지 않는다고 말하는거야? –

+0

@ shiplu.mokadd.im : 1 바이트 문자열은 NUL 종료 될 수 있지만 'row' 문자열 배열은'NULL '종료되지 않습니다. –

+0

나는 [mysql_fetch_lengths] (http://dev.mysql.com/doc/refman/5.1/en/mysql-fetch-lengths.html)를 사용해야한다고 생각한다. –