当前位置: 技术问答>linux和unix
请教两段C代码,关于sqlite数据库操作的
来源: 互联网 发布时间:2017-05-05
本文导语: 使用valgrind进行内存泄漏,发现sqlite3_get_table处有泄漏,泄漏代码如下: void EXE_Send2Low_Ent() { char buf[1000]; //数据库操作 char DataID[20]; ...
使用valgrind进行内存泄漏,发现sqlite3_get_table处有泄漏,泄漏代码如下:
这两段函数实现了一个函数调用参数传递的过程,SqlDbase子函数里使用sqlite3_get_table后在EXE_Send2Low_Ent父函数里使用sqlite3_free_table进行了释放,理论上不应该在这里出现内存泄漏,但实际用valgrind检测还是会显示这里有内存泄漏,如下:
==10834== 1,168 bytes in 73 blocks are definitely lost in loss record 21 of 23
==10834== at 0x402C1C2: realloc (vg_replace_malloc.c:687)
==10834== by 0x4077233: sqlite3MemRealloc (sqlite3.c:15811)
==10834== by 0x4059D0C: sqlite3Realloc (sqlite3.c:19305)
==10834== by 0x40C8CAE: sqlite3_get_table (sqlite3.c:101462)
==10834== by 0x804DFC7: EXE_Send2Low_Ent (Send2Low_Enterprise.c:64)
==10834== by 0x804F344: CommRTU (RTU.c:61)
==10834== by 0x4103D77: start_thread (pthread_create.c:311)
==10834== by 0x435FFED: clone (clone.S:131)
我猜测是valgrind很“死板”只对单个函数内sqlite3_get_table和sqlite3_free_table是否配对进行检测,所以我修改代码如下:
在子函数内直接重新定义结构体,在子函数内进行显示的释放,通过这种操作,再使用valgrind进行检测,果然发现没有内存泄漏了,但出现了另一个问题,在这里出现Segmentation fault (core dumped)错误!导致程序无法运行!
请各位大牛给点建议,谢谢!
void EXE_Send2Low_Ent()
{
char buf[1000]; //数据库操作
char DataID[20]; //指令ID号
char OrderTxt[200]; //指令类容
nt_Table tb;
sprintf( buf, "select * from Send2Low_Enterprise order by DataID ASC"); //获取数据库中第一条命令
if( SqlDbase( &tb, buf ) == -1){
return; //操作失败
}
if( (tb.row) == 0){ //没有需要处理的命令
return;
}
if((tb.row) > OrderMax_Ent){ //指令堆积,删除指令后退出
sprintf( buf, "delete from Send2Low_Enterprise");
ExecDbase( buf ); //删除表中所有指令
return ;
}
strcpy(DataID, tb.result[2]); //获取要处理指令的编号(第一条指令)
strcpy(OrderTxt,tb.result[3]); //获取要处理指令的内容
#ifdef DEBUG_TEST
printf("The EXE_Send2Low_Ent ID is %sn", DataID);
printf("The EXE_Send2Low_Ent OrderTxt is %sn", OrderTxt);
#endif
sprintf( buf, "delete from Send2Low_Enterprise where DataID = %s", DataID);
if( ExecDbase( buf ) ) { //删除该条命令记录
return ;
}
sqlite3_free_table( tb.result ); //释放查询结果
EXE_Send2Low_Handle(OrderTxt); //处理该命令
return;
}
int SqlDbase( nt_Table * tb, char * sql )
{
char *pErrMsg;
//nt_Table tb_t;
if(db.pdb == NULL)
{
return -1;
}
pthread_mutex_lock(&dbase_lock) ; // 数据库上锁
sqlite3_get_table(db.pdb, sql, &(tb->result), &(tb->row), &(tb->col), &pErrMsg);
pthread_mutex_unlock(&dbase_lock); // 数据库解锁
if(pErrMsg != NULL)
{
printf("error: sql %s, %sn", sql, pErrMsg );
sqlite3_free(pErrMsg);
//pErrMsg = NULL;
return -1;
}
return 0;
}
这两段函数实现了一个函数调用参数传递的过程,SqlDbase子函数里使用sqlite3_get_table后在EXE_Send2Low_Ent父函数里使用sqlite3_free_table进行了释放,理论上不应该在这里出现内存泄漏,但实际用valgrind检测还是会显示这里有内存泄漏,如下:
==10834== 1,168 bytes in 73 blocks are definitely lost in loss record 21 of 23
==10834== at 0x402C1C2: realloc (vg_replace_malloc.c:687)
==10834== by 0x4077233: sqlite3MemRealloc (sqlite3.c:15811)
==10834== by 0x4059D0C: sqlite3Realloc (sqlite3.c:19305)
==10834== by 0x40C8CAE: sqlite3_get_table (sqlite3.c:101462)
==10834== by 0x804DFC7: EXE_Send2Low_Ent (Send2Low_Enterprise.c:64)
==10834== by 0x804F344: CommRTU (RTU.c:61)
==10834== by 0x4103D77: start_thread (pthread_create.c:311)
==10834== by 0x435FFED: clone (clone.S:131)
我猜测是valgrind很“死板”只对单个函数内sqlite3_get_table和sqlite3_free_table是否配对进行检测,所以我修改代码如下:
int SqlDbase( nt_Table * tb, char * sql )
{
char *pErrMsg;
nt_Table tb_t;
if(db.pdb == NULL)
{
return -1;
}
pthread_mutex_lock(&dbase_lock) ; // 数据库上锁
sqlite3_get_table(db.pdb, sql, &(tb_t.result), &(tb_t.row), &(tb_t.col), &pErrMsg);
pthread_mutex_unlock(&dbase_lock); // 数据库解锁
if(pErrMsg != NULL)
{
printf("error: sql %s, %sn", sql, pErrMsg );
sqlite3_free(pErrMsg);
//pErrMsg = NULL;
return -1;
}
tb->result = tb_t.result;
tb->row = tb_t.row;
tb->col = tb_t.col;
sqlite3_free_table(tb_t.result);
return 0;
}
在子函数内直接重新定义结构体,在子函数内进行显示的释放,通过这种操作,再使用valgrind进行检测,果然发现没有内存泄漏了,但出现了另一个问题,在这里出现Segmentation fault (core dumped)错误!导致程序无法运行!
请各位大牛给点建议,谢谢!
|
valgrind误报?