This is a really novice question, but I don’t write C unless (err, if) I can avoid it 😉
I’ve written a small extension to ruby that needed to interface with libmysql. It works as expected, but now I’m in some doubt as to whether two lines of code a resulting in a possible memory leak.
Inside a tight loop I’m using functions MYSQL_FIELD * mysql_fetch_fields( ... ) and unsigned long * mysql_fetch_lengths( ... ).
Since these functions return arrays, I assume they would use malloc() therefore require the user to call free() manually when finished with the result? I expected this to be documented in the manual, but it’s not, so I assume this is one of those things C developers just do instinctively: http://dev.mysql.com/doc/refman/5.0/en/mysql-fetch-fields.html
Any pointers? (in the advice sense ;))
The code in question is here: https://github.com/d11wtq/oedipus/blob/master/ext/oedipus/oedipus.c#L137-138
EDIT | Ugh, now I have a doubt. It is documented to call mysql_free_result() on the result set, which was passed to mysql_fetch_fields(), so perhaps this is just returning a pointer to something that’s already on the heap, from that MYSQL_RES struct.
EDIT 2 | Sorry for the noise. It does appear that this information is just pulled from the MYSQL_RES struct which is an argument to mysql_fetch_fields(), and is itself freed later, so I’m probably fine:
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;
You need to call
mysql_free_result(result)where result is the result ofmysql_fetch_fields. C developers are used to this programming paradigm, but there is no one function you call to free something allocated in another library. Each library will have functions that allocate and return something, then a function to free the results of the allocation. The client can’t free it itself withfreeordeleteas it may be allocated on a different heap, and may be a complex object with multiple allocations inside.