这是一个非常新手的问题,但我不写C,除非(错误,如果)我可以避免它;)
我已经为ruby编写了一个小扩展,需要与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}}
答案 0 :(得分:4)
您需要致电mysql_free_result(result)
,其中结果是mysql_fetch_fields
的结果。 C开发人员习惯于这种编程范例,但是没有一个函数可以调用来释放在另一个库中分配的东西。每个库都有分配和返回内容的函数,然后是一个释放分配结果的函数。客户端无法使用free
或delete
释放它本身,因为它可能在不同的堆上分配,并且可能是一个内部有多个分配的复杂对象。
答案 1 :(得分:1)
到目前为止您使用的API参考提供了答案:您需要使用mysql_free_result()
函数从结果集中释放内存:
释放为
mysql_store_result()
的结果集分配的内存,mysql_use_result()
,mysql_list_dbs()
等等。当你是 完成结果集后,您必须通过调用释放它使用的内存mysql_free_result()
。释放后不要尝试访问结果集。
是的,C程序员习惯于为返回的对象提供_free()
例程的API。它只是该地区的一部分。
答案 2 :(得分:0)
函数mysql_store_result
将查询的整个结果存储在堆中,并返回包含指向所有数据的指针的结构。像mysql_fetch_row
和mysql_fetch_fields
这样的函数只返回部分数据。函数mysql_free_result
负责释放整个结果数据,包括返回的字段mysql_fetch_fields
。
因此,您只需在使用数据后调用mysql_free_result
,它就能完成工作。