valgrind 报告 ecpg内存泄露 (四)
我运行测试后的结论是这样的:确实发生了内存泄漏。没有回收sqlca区域。
因为,我修改了 /src/interfaces/ecpg/ecpglib/misc.c的代码后,
#ifdef ENABLE_THREAD_SAFETY static void ecpg_sqlca_key_destructor(void *arg) { FILE *p1; p1=fopen("gaoecpg.1","w+"); fclose(p1); free(arg); /* sqlca structure allocated in ECPGget_sqlca */ FILE *p2; p2=fopen("gaoecpg.2","w+"); fclose(p2); } static void ecpg_sqlca_key_init(void) { FILE *p3; p3=fopen("gaoecpg.3","w+"); fclose(p3); pthread_key_create(&sqlca_key, ecpg_sqlca_key_destructor); FILE *p6; p6=fopen("gaoecpg.6","w+"); fclose(p6); } #endif struct sqlca_t * ECPGget_sqlca(void) { #ifdef ENABLE_THREAD_SAFETY FILE *p4; p4=fopen("gaoecpg.4","w+"); fclose(p4); struct sqlca_t *sqlca; pthread_once(&sqlca_key_once, ecpg_sqlca_key_init); sqlca = pthread_getspecific(sqlca_key); if (sqlca == NULL) { sqlca = malloc(sizeof(struct sqlca_t)); ecpg_init_sqlca(sqlca); pthread_setspecific(sqlca_key, sqlca); } return (sqlca); #else FILE *p5; p5=fopen("gaoecpg.5","w+"); fclose(p5); return (&sqlca); #endif }
无论连接是成功还是失败,都生成三个文件:
gaoecpg.3,gaoecpg.4, gaoecpg.6
下面是我的测试程序 :
#include <stdio.h> #include <string.h> #include <stdlib.h> int cm_connectdb(const char *DbUid,const char *DbPswd,const char *Hostname,char *pcSqlErrm) { EXEC SQL BEGIN DECLARE SECTION; varchar sUserid[20]; varchar sPasswd[20]; varchar sHostname[64]; EXEC SQL END DECLARE SECTION; memset(sUserid.arr, '\0',sizeof(sUserid.arr)); memset(sPasswd.arr, '\0',sizeof(sPasswd.arr)); memset(sHostname.arr, '\0',sizeof(sHostname.arr)); if (DbUid == NULL || DbPswd == NULL || Hostname == NULL || pcSqlErrm == NULL){ return -1; } strcpy((char *)sUserid.arr, DbUid); sUserid.len = (unsigned short)strlen((char *)sUserid.arr); strcpy((char *)sPasswd.arr, DbPswd); sPasswd.len = (unsigned short)strlen((char *)sPasswd.arr); strcpy((char *)sHostname.arr, Hostname); sHostname.len = (unsigned short)strlen((char *)sHostname.arr); EXEC SQL CONNECT TO :sHostname AS CM_DBCONN USER:sUserid IDENTIFIED BY :sPasswd; if (sqlca.sqlcode!=0){ fprintf(stderr,"Connection Failed.\n"); EXEC SQL DISCONNECT CM_DBCONN; return -1; }else{ fprintf(stderr,"Connection Succeeded!\n"); } EXEC SQL DISCONNECT CM_DBCONN; return 0; } int main(){ int ist=0; char * perr; perr = (char *) malloc (sizeof(char)*64); const char * pusr="postgres"; const char * ppass="postgres"; const char * phost="postgres@localhost:5432"; ist= cm_connectdb(pusr,ppass,phost,perr); free(perr); return 0; }
虽然,按照网上的说法,理论上:线程结束的时候,就会自动调用pthread_key_create注册的函数
但是至少我遇到的情况,并非如此。