2010-04-24 4 views
2

Une routine normale de sqlite3_prepare_v2() + sqlite3_step() + sqlite3_finalize() peut contenir des fuites.Y at-il une fuite de mémoire dans la routine normale de sqlite3 _ *()?

Cela semble ridicule. Mais le code de test semble le dire. Ou j'ai utilisé le sqlite3 _ *() à tort.

Appréciez-vous pour toute réponse.

#include <stdio.h> 
#include <unistd.h>  // for usleep() 
#include <sqlite3.h> 


int multi_write (int j); 

sqlite3 *db = NULL; 

int main (void) 
{ 
    int ret = -1; 

    ret = sqlite3_open("test.db", &db); 
    ret = sqlite3_exec(db,"CREATE TABLE data_his (id INTEGER PRIMARY KEY, d1 CHAR(16))", NULL,NULL,NULL); 
    usleep (100000); 


    int j=0; 
    while (1) 
    { 
     multi_write (j++); 
     usleep (2000000); 
     printf (" ----------- %d\n", j); 
    } 


    ret = sqlite3_close (db); 
    return 0; 
} 


int multi_write (int j) 
{ 
    int ret = -1; 

    char *sql_f = "INSERT OR REPLACE INTO data_his VALUES (%d, %Q)"; 
    char *sql = NULL; 

    sqlite3_stmt *p_stmt = NULL; 


    ret = sqlite3_prepare_v2 (db, "BEGIN TRANSACTION", -1, &p_stmt, NULL); 
    ret = sqlite3_step (p_stmt); 
    ret = sqlite3_finalize (p_stmt); 

    int i=0; 
    for (i=0; i<100; i++) 
    { 
     sql = sqlite3_mprintf (sql_f, j*100000 + i, "00000000000068FD"); 

     ret = sqlite3_prepare_v2 (db, sql, -1, &p_stmt, NULL); 
     sqlite3_free (sql); 
     //printf ("sqlite3_prepare_v2(): %d, %s\n", ret, sqlite3_errmsg (db)); 

     ret = sqlite3_step (p_stmt); 
     //printf ("sqlite3_step():  %d, %s\n", ret, sqlite3_errmsg (db)); 

     ret = sqlite3_finalize (p_stmt); 
     //printf ("sqlite3_finalize(): %d, %s\n\n", ret, sqlite3_errmsg (db)); 
    } 

    ret = sqlite3_prepare_v2 (db, "COMMIT TRANSACTION", -1, &p_stmt, NULL); 
    ret = sqlite3_step (p_stmt); 
    ret = sqlite3_finalize (p_stmt); 


    return 0; 
} 

Et je regarde le déroulement du processus par le haut.

Dans un premier temps, les statistiques de la mémoire est:

PID  PPID USER  STAT VSZ %MEM %CPU COMMAND 
17731 15488 root  S  1104 5% 7% ./sqlite3multiwrite 

Lorsque le printf() dans while (1) {} de main() imprime 150, les statistiques de la mémoire est:

PID  PPID USER  STAT VSZ %MEM %CPU COMMAND 
17731 15488 root  S  1552 5% 7% ./sqlite3multiwrite 

Il semble qu'après 150 cycles, la mémoire utilisée par sqlite3multiwrite passe de 1104KB à 1552KB.

Qu'est-ce que cela signifie? fuite de mémoire ou autre chose?

+0

Qu'advient-il lorsque vous exécutez avec valgrind? – nc3b

+0

Pouvez-vous coller la sortie de valgrind? –

Répondre

2

Utilisez Valgrind. La croissance de 1,1 Mo à 1,5 Mo n'est pas très importante, surtout sur 150 itérations. SQLite peut, par exemple, faire de la mise en cache (il réserve de la mémoire à l'avance). Essayez d'autres itérations - il y a peut-être une valeur seuil sur laquelle votre programme ne peut pas croître. Mais Valgrind est l'outil le plus précis pour détecter les fuites de mémoire.

+0

Merci beaucoup! vous êtes mon premier replicateur dans stackoveflow.com. :) Parce que mon système a juste 32M de RAM. Alors que printf() dans while (1) {} de main() imprime le 161939, le processus est automatiquement détruit par le système. Il semble donc qu'il y ait de véritables fuites de mémoire dans le code. Et lors de l'observation de sqlite3_step(), la mémoire du processus n'augmente pas. C'est une chose déroutante. Il semble dire qu'il y a une fuite de mémoire dans sqlite3_step(). – reer

+0

+1, De plus, je trouve l'outil Massif Heap profiler de Valgrind extrêmement utile dans ce genre d'exemple. –