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.
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.