IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Fuites mémoire avec sqlite3


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 35
    Par défaut Fuites mémoire avec sqlite3
    Bonjour,

    Pour voir les fuites mémoire de mon programme j'utilise cette ligne de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./monProgramme 2>mem.log
    J'obtiens énormément d'erreurs (voici un très court extrait de mon mem.log) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    ==6361== Memcheck, a memory error detector
    ==6361== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
    ==6361== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
    ==6361== Command: ./monProgramme
    ==6361== 
    ==6361== Invalid read of size 1
    ==6361==    at 0x80DA394: sqlite3Prepare 
    ==6361==    by 0x80DAC1C: sqlite3LockAndPrepare 
    ==6361==    by 0x80515AA: SF (sql.c:184)
    ==6361==    by 0x804FBB4: ---
    ==6361==    by 0x8049A4E: ---
    ==6361==    by 0x804EE2E: main (main.c:114)
    ==6361==  Address 0x4562f5f is not stack'd, malloc'd or (recently) free'd
    ==6361== 
    ==6361== Invalid read of size 1
    ==6361==    at 0x80DA394: sqlite3Prepare 
    ==6361==    by 0x80DAC1C: sqlite3LockAndPrepare 
    ==6361==    by 0x8051675: SF (sql.c:201)
    ==6361==    by 0x804FBB4: ---
    ==6361==    by 0x8049A4E: ---
    ==6361==    by 0x804EE2E: main (main.c:114)
    ==6361==  Address 0x4562f07 is 207 bytes inside a block of size 1,048 free'd
    ==6361==    at 0x402B06C: free (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==6361==    by 0x813A91C: ---
    ==6361==    by 0x81377AF: sqlite3_memalloc_free
    ==6361==    by 0x80D49D0: sqlite3RunParser 
    ==6361==    by 0x80DA5E5: sqlite3Prepare
    ==6361==    by 0x80DAC1C: sqlite3LockAndPrepare 
    ==6361==    by 0x80515AA: SF (sql.c:184)
    ==6361==    by 0x804FBB4: ---
    ==6361==    by 0x8049A4E: ---
    ==6361==    by 0x804EE2E: main (main.c:114)
    ==6361== 
     
    PLEIN D'AUTRES "Invalid read of size 1"
     
    ==6361== Invalid read of size 1
    ==6361==    at 0x80DA394: sqlite3Prepare 
    ==6361==    by 0x80DAC1C: sqlite3LockAndPrepare
    ==6361==    by 0x80519A8: SFW (sql.c:266)
    ==6361==    by 0x804FF50: ---
    ==6361==    by 0x8049A4E: ---
    ==6361==    by 0x804EE2E: main (main.c:114)
    ==6361==  Address 0x45682df is not stack'd, malloc'd or (recently) free'd
    ==6361== 
     
    ==6361== Use of uninitialised value of size 4
    ==6361==    at 0x80DABA5: sqlite3LockAndPrepare 
    ==6361==    by 0x8051C26: SFW2 (sql.c:311)
    ==6361==    by 0x804B18D: --- (fonction de test)
    ==6361==    by 0x804EE8C: main (main.c:239)
    ==6361== 
    ==6361== Conditional jump or move depends on uninitialised value(s)
    ==6361==    at 0x806770B: sqlite3DbMallocRaw 
    ==6361==    by 0x80DA157: sqlite3Prepare 
    ==6361==    by 0x80DAC1C: sqlite3LockAndPrepare 
    ==6361==    by 0x8051C26: SFW2 (sql.c:311)
    ==6361==    by 0x804B18D: ---
    ==6361==    by 0x804EE8C: main (main.c:239)
    ==6361== 
     
    ==6361== 
    ==6361== LEAK SUMMARY:
    ==6361==    definitely lost: 29,247 bytes in 1,931 blocks
    ==6361==    indirectly lost: 912,663 bytes in 7,434 blocks
    ==6361==      possibly lost: 17,485 bytes in 38 blocks
    ==6361==    still reachable: 101,951 bytes in 55 blocks
    ==6361==         suppressed: 0 bytes in 0 blocks
    ==6361== 
    ==6361== For counts of detected and suppressed errors, rerun with: -v
    ==6361== Use --track-origins=yes to see where uninitialised values come from
    ==6361== ERROR SUMMARY: 14163 errors from 1033 contexts (suppressed: 0 from 0)
    Voici quelques fonctions dont il est question.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    int * SF(sqlite3 *conn, const char * idFieldName, const char * tableName)
    {
    	int * id=NULL;
    	sqlite3_stmt * res=NULL;
     	int error = 0;
      	const char * tail="";
    	char * request="";
    	char * request2="";
    	int rec_count=0;
    	int size2=0;
    	int id_size=0;
    	/* Calculate the request's size */
    	int size = strlen("select  from ");
    	size+=strlen(idFieldName);
    	size+=strlen(tableName);
    	size++;
    	request=malloc(size);
    	memset(request,0,size);
    	snprintf(request, size, "select %s from %s", idFieldName, tableName);
     
    	/* Calculate the "count" request's size */
    	size2 = size + strlen("count()");
    	request2=malloc(size2);
    	memset(request2,0,size2);
    	snprintf(request2, size2, "select count(%s) from %s", idFieldName, tableName);
     
    	error = sqlite3_prepare_v2(conn, request2,NBYTE, &res, &tail);
    	if (error != SQLITE_OK)
    	{
    		---(("EXIT : SF error request2  \n error=%d\n", error));
    		free(request2);
    		return NULL;
    	}
     
    	while (sqlite3_step(res) == SQLITE_ROW)
    	{
    		id_size=sqlite3_column_int(res, 0);
    	}
     
    	sqlite3_finalize(res);
     
    	res=NULL;
    	tail="";
    	error = sqlite3_prepare_v2(conn, request,NBYTE, &res, &tail);
    	if (error != SQLITE_OK)
    	{
    		---(("EXIT : SF error request  \n error=%d\n", error));
    		free(request);
    		return NULL;
    	}
     
    	rec_count=0;
    	id=malloc(id_size*BUFSIZE_INT);
     
    	while (sqlite3_step(res) == SQLITE_ROW)
    	{
    		id[rec_count+1]=sqlite3_column_int(res, 0);
     
    		rec_count++;
    	}
    	id[0]=rec_count;/* Get the array of id */
    	sqlite3_finalize(res);
     
    	free(request);
    	return id;/* Return the array of id */
    }
    int SFW(sqlite3 *conn, const char * tableName, const char * name)
    {
    	int id=0;
    	sqlite3_stmt * res=NULL;
     	int error = 0;
      	const char * tail="";
    	char * request="";
     
    	/* Calculate the request's size */
    	int size =strlen("select  from  where =''");
     
    	size+=strlen(tableName);
    	size+=strlen(name);
    	size++;
     
    	if(strcmp(tableName,TABLE_PROFILE)==0)
    	{
    		size+=strlen(LABEL_ID_PROFILE);
    		size+=strlen(LABEL_ID_PROFILE);
    		request=malloc(size);
    		memset(request,0,size);
    		snprintf(request, size, "select %s from %s where %s='%s'", LABEL_ID_PROFILE, tableName, LABEL_ID_PROFILE, name);
    	}
     
    	else if(strcmp(tableName,TABLE_ACTIVITIES)==0)
    	{
    		size+=strlen(LABEL_RATING);
    		size+=strlen(LABEL_ID);
    		request=malloc(size);
    		memset(request,0,size);
    		snprintf(request, size, "select %s from %s where %s='%s'", LABEL_RATING, tableName, LABEL_ID, name);
    	}
    	else
    	{
    		size+=strlen(LABEL_ID);
    		size+=strlen(LABEL_NAME);
    		request=malloc(size);
    		memset(request,0,size);
    		snprintf(request, size, "select %s from %s where %s='%s'", LABEL_ID, tableName, LABEL_NAME, name);
    	}
     
    	error = sqlite3_prepare_v2(conn, request, NBYTE, &res, &tail);
    	if (error != SQLITE_OK)
    	{
    		---(("EXIT : SFW error request 1 %s\n  error=%d\n", request, error));
    		free(request);
    		return -1;
    	}
    	if (sqlite3_step(res) != SQLITE_ROW)
    	{
    		free(request);
    		return -1;
    	}
    	id=sqlite3_column_int(res, 0);/* Get the id */
    	sqlite3_finalize(res);
    	free(request);
    	return id; /* Return the id */
    }
    int * SFW2(sqlite3 *conn, const char * tableName, const char * labelName, const char * name)
    {
    	int * id=NULL;
    	sqlite3_stmt * res=NULL;
     	int error = 0;
      	const char * tail="";
    	char * request="";
    	char * request2="";
    	int idx=1;
    	int size2=0;
    	int id_size=0;
    	/* Calculate the request's size */
    	int size =strlen("select  from  where  like ''");
    	size+=strlen(tableName);
    	size+=strlen(name);
    	size++;
    	size+=strlen(LABEL_ID_PRODUCT);
    	size+=strlen(labelName);
    	request=malloc(size);
    	memset(request,0,size);
    	snprintf(request, size, "select %s from %s where %s like '%s'", LABEL_ID_PRODUCT, tableName, labelName, name);
     
    	/* Calculate the "count" request's size */
    	size2 = size + strlen("count()");
    	request2=malloc(size2);
    	memset(request2,0,size2);
    	snprintf(request2, size2, "select count(%s) from %s where %s like '%s'", LABEL_ID_PRODUCT, tableName, labelName, name);
     
    	error = sqlite3_prepare_v2(conn, request2,NBYTE, &res, &tail);
    	if (error != SQLITE_OK)
    	{
    		---(("EXIT : SFW2 error request2  \n error=%d\n", error));
    		free(request2);
    		return NULL;
    	}
     
    	while (sqlite3_step(res) == SQLITE_ROW)
    	{
    		id_size=sqlite3_column_int(res, 0);/* Get the number of id */
    	}
    	sqlite3_finalize(res);
    	res=NULL;
    	tail="";
    	error = sqlite3_prepare_v2(conn, request, NBYTE, &res, &tail);
    	if (error != SQLITE_OK)
    	{
    		---(("EXIT : SFW2 error request 1 %s\n  error=%d\n", request, error));
    		free(request);
    		return NULL;
    	}
     
    	id=malloc(id_size*BUFSIZE_INT);	
    	memset(id,0,id_size*BUFSIZE_INT);
     
    	while (sqlite3_step(res) == SQLITE_ROW)
    	{
    		id[idx]=sqlite3_column_int(res, 0);/* Get the id */
    		idx++;
    	}
    	id[0]=id_size;
    	sqlite3_finalize(res);
    	free(request);
    	return id; /* Return the id */
    }
    Mes principales fuites mémoire ne viennent pas de ces derniers, cependant je me demande d'ou viennent ces "invalide read".
    J'ai vérifié les fonctions d'avant mais rien de choquant.
    Sauriez vous?
    Merci

  2. #2
    Membre émérite
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Par défaut
    Bonjour

    Beaucoup de malloc qui peuvent créer des problèmes.
    As tu essayer avec des chaînes fixes pou debuger ? char request[512] = "" ;


    Bonne continuation.

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Valgrind te donne les lignes où tu alloues sans libérer la mémoire, si tu veux qu'on t'aide il faudrait nous montrer ces lignes et les mettre en valeur qu'on puisse les retrouver.

    Cela ne sert à rien de nous montrer les erreurs si tu ne nous montre pas où sont les lignes incriminées.

  4. #4
    Membre émérite
    Avatar de Elijha
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Avril 2003
    Messages
    314
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Avril 2003
    Messages : 314
    Par défaut
    Bonsoir,

    Dans les fonctions où tu utilises request2, tu libères la mémoire allouée qu'en cas d'erreur. Il faut libérer cette mémoire par un free(request2) ; au même niveau que le free(request) ;. Idem pour le pointeur id.

    En gros, pour un malloc utilisé, il te faut un free derrière quand tu n'as plus besoin de la mémoire. Le fait de sortir de la fonction ne libère pas la mémoire précédement allouée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    char *test = NULL ;
     
    // Allocation et vérification
    test = malloc(size) ;
    if(test==NULL) {
        fprintf(stderr, "Erreur d'allocation mémoire.\n") ;
        return EXIT_FAILURE ;
    }
     
    // ... utilisation de test
     
    free(test) ;     // Libération de test
    test = NULL ;   // Au cas où on doit réutiliser le pointeur

    Bonne continuation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Détection de fuites mémoire avec Valgrind
    Par dj.motte dans le forum GTK+ avec C & C++
    Réponses: 25
    Dernier message: 22/11/2008, 08h49
  2. Fuite mémoire avec code externe
    Par samW7 dans le forum C++
    Réponses: 8
    Dernier message: 01/02/2008, 02h33
  3. [AJAX] Appolo 13 - Fuite mémoire avec XHR
    Par mecatroid dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/09/2007, 14h52
  4. Fuites mémoires avec Vector
    Par ..alex.. dans le forum SL & STL
    Réponses: 15
    Dernier message: 10/08/2006, 11h35
  5. Fuite mémoire avec valgrind
    Par franchouze dans le forum C++
    Réponses: 3
    Dernier message: 05/06/2006, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo