fuite de mémoire

fuite de mémoire - C - Programmation

Marsh Posté le 03-05-2010 à 17:09:45    

Bonjour,
J'ai ce prog. en C qui est devenu gourmand en mémoire en incrémentant le nombre d'appel de la fonction.

Code :
  1. void publishkw(const char *addr, const char *targetid, int srcid, const char *fileid, int sybilid)
  2.  
  3. {
  4.  PGresult* result1;
  5.  PGresult* resultp1;
  6.  PGresult* resultkw1;
  7.  char commande_sql1[128];
  8.  char publish1[128];
  9.  char kw1[128];
  10.  
  11.  
  12.  sprintf(commande_sql1,"select verify_replicat('%s', '%s', current_timestamp);", addr, targetid);
  13.  result1 = PQexec(connect_database, commande_sql1);
  14.  char *val1 = PQgetvalue(result1,0,0);
  15.  printf("%s \n", val1);
  16.  
  17.  if ((PQresultStatus(result1) != PGRES_TUPLES_OK ))
  18.    {
  19.      fprintf(stderr, "couldn't execute query publish\n" );
  20.    
  21.      PQclear(result1);
  22.        
  23.    }
  24.  else {
  25.    printf ("commande publish exécutée\n" );
  26.  }
  27.  if ((strcmp(val1,"1" ) == 0))
  28.    {sprintf(publish1,"select mape_publish (date_trunc('minute',current_timestamp), %d, '%s', '%s', %d);", srcid, fileid, targetid, sybilid);
  29.      resultp1 =  PQexec(connect_database, publish1);
  30.      char *pub1 = PQgetvalue(resultp1,0,0);
  31.      printf ("%s \n", pub1);
  32.      if ((PQresultStatus(resultp1) != PGRES_TUPLES_OK))
  33.        {
  34.          fprintf(stderr, "couldn't execute query pub\n" );
  35.    
  36.          PQclear(resultp1);
  37.            
  38.        }
  39.      else {
  40.        printf ("commande pub exécutée\n" );
  41.  
  42.        sprintf(kw1,"select kw_files('%s', '%s', %d);", fileid, targetid, srcid);
  43.        resultkw1 = PQexec(connect_database, kw1);
  44.        char *key1 = PQgetvalue(resultkw1,0,0);
  45.        printf ("%s \n", key1);
  46.  
  47.        if ((PQresultStatus(resultkw1) != PGRES_TUPLES_OK))
  48.          {
  49.            fprintf(stderr, "couldn't execute query key_pub\n" );
  50.    
  51.            PQclear(resultkw1);
  52.          }
  53.        else {
  54.          printf ("commande key_pub exécutée\n" );
  55.        }
  56.      }
  57.      PQclear(result1);
  58.      PQclear(resultp1);
  59.      PQclear(resultkw1);
  60.    }
 


pouvez vous m'indiquer l'erreur ou la solution pour libérer la mémoire à la fin de la fonction?


Message édité par gilou le 03-05-2010 à 22:00:31
Reply

Marsh Posté le 03-05-2010 à 17:09:45   

Reply

Marsh Posté le 03-05-2010 à 17:23:14    

Sans vouloir etre mechant, commence par indenter ton code et poster sans les numeros de ligne qui pourrissent la balise code et tu aura qq chances de voir qq se plonger dans ton probleme. La ca me donne juste envie d'aller surfer ailleurs et je ne dois pas etre le seul :(

Reply

Marsh Posté le 03-05-2010 à 17:35:02    

et ça te convient maintenant?

Reply

Marsh Posté le 03-05-2010 à 17:59:23    

Peut-être que cela irait mieux en remontant le PQclear(result1); de la ligne 57 vers la ligne 29 et le PQclear(resultp1); de la ligne 58 vers la ligne 43, c'est à dire avant le prochain PQexec(). Si on a besoin d'une valeur plus loin, alors on peut la copier dans une autre variable. Voir la doc, http://www.network-theory.co.uk/do [...] ation.html

Reply

Marsh Posté le 03-05-2010 à 22:20:44    

En réarrangeant le code, et en ne faisant pas un appel à tout de suite a PQgetvalue sans tester d'abord le code retour de la query (c'est au pif, vu que je connais pas l'API, mais ça semble logique a la lecture du code) et en corrigeant le pb d'appeller if ((strcmp(val1,"1" ) == 0)) quand ca a foiré et que val1 n'a peut être pas de valeur valable, j'obtiens:

Code :
  1. void publishkw(const char *addr, const char *targetid, int srcid, const char *fileid, int sybilid) {
  2.  
  3.  PGresult* result1;
  4.  PGresult* resultp1;
  5.  PGresult* resultkw1;
  6.  char commande_sql1[128];
  7.  char publish1[128];
  8.  char kw1[128];
  9.  
  10.  sprintf(commande_sql1,"select verify_replicat('%s', '%s', current_timestamp);", addr, targetid);
  11.  result1 = PQexec(connect_database, commande_sql1);
  12.  if ((PQresultStatus(result1) != PGRES_TUPLES_OK )) {
  13.    fprintf(stderr, "couldn't execute query publish\n" );
  14.  }
  15.  else {
  16.    char *val1;
  17.    printf ("commande publish exécutée\n" );
  18.    val1 = PQgetvalue(result1,0,0);
  19.    printf("%s \n", val1);
  20.  
  21.    if ((strcmp(val1,"1" ) == 0)) {
  22.      sprintf(publish1,"select mape_publish (date_trunc('minute',current_timestamp), %d, '%s', '%s', %d);", srcid, fileid, targetid, sybilid);
  23.      resultp1 =  PQexec(connect_database, publish1);
  24.      if ((PQresultStatus(resultp1) != PGRES_TUPLES_OK)) {
  25.        fprintf(stderr, "couldn't execute query pub\n" );  
  26.      }
  27.      else {
  28.        char *pub1;
  29.        printf ("commande pub exécutée\n" );
  30.        pub1 = PQgetvalue(resultp1,0,0);
  31.        printf ("%s \n", pub1);  
  32.  
  33.        sprintf(kw1,"select kw_files('%s', '%s', %d);", fileid, targetid, srcid);
  34.        resultkw1 = PQexec(connect_database, kw1);
  35.        if ((PQresultStatus(resultkw1) != PGRES_TUPLES_OK)) {
  36.          fprintf(stderr, "couldn't execute query key_pub\n" );
  37.        }
  38.        else {
  39.          char *key1;
  40.          printf ("commande key_pub exécutée\n" );
  41.          key1 = PQgetvalue(resultkw1,0,0);
  42.          printf ("%s \n", key1);
  43.        }
  44.        PQclear(resultkw1);
  45.      }
  46.      PQclear(resultp1);  
  47.    }
  48.  }
  49.  PQclear(result1);
  50. }

Si les 3 appels à PQgetvalue allouent de la place, elle n'est désallouée nulle part. Sinon, si PQgetvalue retourne un pointeur quelque part sur son premier argument, ça semble OK (edit: j'ai été voir, et c'est le cas).
Autre chose: connect_database semble être une globale, il vaudrait mieux l'incorporer au prototype de la fonction:
void publishkw(PGconn *connect_database, const char *addr, const char *targetid, int srcid, const char *fileid, int sybilid);
A+,


Message édité par gilou le 04-05-2010 à 10:05:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 04-05-2010 à 10:11:13    

Bonjour,
 
Cool, ça marche très bien.
Je vous remercie infiniment.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed