0

我在这个函数上遇到了段错误。

/**
 * 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 运行它。输出和相应的代码可以在这里找到

4

1 回答 1

3

g_strdupv()复制一个NULL以 C 字符串结尾的数组(每个字符串都必须以 NUL 结尾)。C API 数据结构上的 MySQL 文档指出这MYSQL_ROW是一个字节字符串数组,不一定以 NUL 结尾“如果字段值可能包含二进制数据”。因此 aMYSQL_ROW既不能保证是 -NULL终止的数组,也不能保证是 C 字符串的数组。

段错误很可能发生,因为g_strdupv()一直在寻找NULL终止符,但直到它尝试读取非进程内存时才找到终止符。

于 2012-07-16T13:24:15.360 回答