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注册的函数

但是至少我遇到的情况,并非如此。

你可能感兴趣的:(内存泄露)