zoukankan      html  css  js  c++  java
  • 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注册的函数

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

  • 相关阅读:
    HDOJ-1106
    二进制神题--一千个苹果问题
    HDOJ-2160
    HDOJ-2058
    HDOJ-2045
    HDOJ-2034
    HDOJ-2054
    HDOJ-2036
    F
    B
  • 原文地址:https://www.cnblogs.com/gaojian/p/2650781.html
Copyright © 2011-2022 走看看