Description:
My program got a signal of segmentation fault and i got to know it was caused by a call to mysql_free_result function.
Codes following:
/******** db_mysql.h file *******/
#ifndef _DB_MYSQL_H
#define _DB_MYSQL_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql.h>
typedef struct {
unsigned long num_rows;
unsigned num_fields;
char (*fields_name)[16], ***row_set;
} ResultSet;
MYSQL *connect_db(void);
unsigned long query(MYSQL *, const char *, ResultSet *);
void close_db(MYSQL *);
void free_rs(ResultSet *);
#ifdef __cpluscplus
#if __cplusplus
}
#endif
#endif
#endif
/********** db_mysql.c file *******/
#include "db_mysql.h"
void close_db(MYSQL *mysql)
{
if(mysql) {
mysql_close(mysql);
mysql = NULL;
}
}
MYSQL *connect_db(void)
{
extern char dbhost[];
extern char dbuser[];
extern char dbpass[];
extern char dbname[];
extern char dbport[];
static MYSQL *mysql = NULL;
if(!mysql) {
if(!(mysql = mysql_init(mysql))) {
fprintf(stderr, "Init MySQL error\n");
return NULL;
}
if(!mysql_real_connect(mysql, dbhost, dbuser, dbpass, dbname, (unsigned)atoi(dbport), NULL, 0)) {
fprintf(stderr, "%s\n", mysql_error(mysql));
close_db(mysql);
return NULL;
}
mysql_query(mysql, "SET NAMES utf8");
}
return mysql;
}
unsigned long query(MYSQL *mysql, const char *sql, ResultSet *rs)
{
MYSQL_RES *res = NULL;
MYSQL_ROW row = NULL;
MYSQL_FIELD *fields = NULL;
unsigned i;
unsigned long j;
if(mysql_query(mysql, sql)) {
fprintf(stderr, "%s\n", mysql_error(mysql));
//close_db(mysql);
return 0;
}
//res = mysql_store_result(mysql);
if(res = mysql_store_result(mysql)) {
rs->num_fields = mysql_num_fields(res);
rs->num_rows = mysql_num_rows(res);
rs->fields_name = (char (*)[16])calloc(rs->num_fields, sizeof(char *));
rs->row_set = (char ***)malloc(rs->num_rows * sizeof(char **));
fields = mysql_fetch_fields(res);
for(i=0; i<rs->num_fields; ++i)
strcpy(*(rs->fields_name+i), fields[i].name);
j = 0;
while(row = mysql_fetch_row(res)) {
*(rs->row_set+j) = (char **)malloc(rs->num_fields * sizeof(char *));
for(i=0; i<rs->num_fields; ++i) {
*(*(rs->row_set+j)+i) = (char *)calloc(strlen(*(row+i))+1, 1);
strcpy(*(*(rs->row_set+j)+i), *(row+i));
}
++j;
}
mysql_free_result(res); //HERE!!! segmentation fault!
} else {
if(mysql_field_count(mysql)) {
fprintf(stderr, "%s\n", mysql_error(mysql));
//close_db(mysql);
return 0;
} else
return 1; //
}
return rs->num_rows;
}
void free_rs(ResultSet *rs)
{
if(rs->row_set) {
unsigned long i;
unsigned j;
for(i=0; i<rs->num_rows; ++i)
if(*(rs->row_set+i)) {
for(j=0; j<rs->num_fields; ++j)
if(*(*(rs->row_set+i)+j)) {
free(*(*(rs->row_set+i)+j));
*(*(rs->row_set+i)+j) = NULL;
}
free(*(rs->row_set+i));
*(rs->row_set+i) = NULL;
}
free(rs->row_set);
rs->row_set = NULL;
}
if(rs->fields_name) {
free(rs->fields_name);
rs->fields_name = NULL;
}
}
How to repeat:
Write a small programe to query a MySQL database using the functions i provided.