2012-04-01 98 views
2

這確實是一個新手的問​​題,但除非(ERR,如果)我能避免它,我不寫C;)使用庫函數返回數組

我寫了一個小的延伸與紅寶石在需要與libmysql進行接口。它按預期工作,但現在我對兩行代碼是否導致內存泄漏有疑問。

在一個緊密的循環內我使用的功能MYSQL_FIELD * mysql_fetch_fields(...)unsigned long * mysql_fetch_lengths(...)

由於這些功能返回陣列,我以爲他們會用malloc()因此要求用戶在與結果完成手動調用free()?我期望將這些記錄在手冊中,但事實並非如此,所以我認爲這是C開發人員本能地做的事情之一:http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-fields.html

任何指針? (在諮詢感;))

有問題的代碼是在這裏:https://github.com/d11wtq/oedipus/blob/master/ext/oedipus/oedipus.c#L137-138

編輯|呃,現在我有疑問了。記錄在結果集上調用mysql_free_result(),該結果集被傳遞給mysql_fetch_fields(),所以也許這只是從該MYSQL_RES結構中返回一個指向已經在堆上的指針。

編輯2 |對不起,噪音。但看來這些信息是剛剛從MYSQL_RES結構這是一個參數mysql_fetch_fields()拉,而它本身以後被釋放,所以我可能罰款:

typedef struct st_mysql_res { 
    my_ulonglong row_count; 
    MYSQL_FIELD *fields; 
    MYSQL_DATA *data; 
    MYSQL_ROWS *data_cursor; 
    unsigned long *lengths;    /* column lengths of current row */ 
    MYSQL   *handle;    /* for unbuffered reads */ 
    const struct st_mysql_methods *methods; 
    MYSQL_ROW  row;     /* If unbuffered read */ 
    MYSQL_ROW  current_row;   /* buffer to current row */ 
    MEM_ROOT  field_alloc; 
    unsigned int field_count, current_field; 
    my_bool  eof;     /* Used by mysql_fetch_row */ 
    /* mysql_stmt_close() had to cancel this result */ 
    my_bool  unbuffered_fetch_cancelled; 
    void *extension; 
} MYSQL_RES; 
+1

你不寫C,除非你能避免它?所以你只有在可以避免時才寫C? :) – 2012-04-01 22:56:05

+0

Mind = blown(: - – d11wtq 2012-04-01 22:57:42

+0

哈哈「如果我可以避免它」或「除非我無法避免它」會適用於你的情況。如果只有英語像C一樣簡單,對嗎? – 2012-04-01 23:02:34

回答

4

你需要調用mysql_free_result(result)其中結果是結果的mysql_fetch_fields。 C開發人員習慣於這種編程模式,但沒有一個函數可以調用來釋放在另一個庫中分配的東西。每個庫都有分配和返回的函數,然後釋放分配結果的函數。客戶端無法使用freedelete自己釋放它,因爲它可能分配在不同的堆上,並且可能是一個內部具有多個分配的複雜對象。

1

到目前爲止已使用的API參考提供了答案:您需要使用mysql_free_result()函數來釋放從結果集的記憶:

釋放分配由mysql_store_result()結果集的記憶, mysql_use_result()mysql_list_dbs()等等。當您使用結果集執行 時,必須通過調用 mysql_free_result()來釋放它使用的內存。

釋放後不要嘗試訪問結果集。

是的,C程序員非常習慣於爲返回對象提供_free()例程的API。這只是該領土的一部分。

0

函數mysql_store_result將查詢的全部結果存儲在堆中,並返回一個包含指向所有數據的指針的結構。像mysql_fetch_rowmysql_fetch_fields這樣的函數只是返回一些這些數據。函數mysql_free_result負責釋放整個結果數據,包括返回的字段mysql_fetch_fields

因此,您只需在使用數據後調用mysql_free_result,它就可以完成工作。