2013-04-06 2 views
1

Cela peut-être finir par être une question idiote. Je l'avais fait la fonction suivante:Fuite de mémoire avec valgrind

char **getArrayOfStrings(int rows, int cols){ 
    int i; 
    char **aux = malloc(rows * sizeof(char*)); 

    for(i = 0; i < rows; i++) 
     aux[i] = malloc(cols+1); 

    return aux; 
} 

Cela me retourne un tableau des 'chaînes', le morceau de code qui importe est quelque chose comme:

void f(...) 
{ 
char **arrayOfStrings; 
    int i = 0; 
    arrayOfStrings = getArrayOfStrings(ROWS,COLS); 

    while(ch != '.' && sscanf (globalString,"%[^,|.]s", arrayOfStrings[i]) > 0)  
    { 
     globalString += strlen(arrayOfStrings[i++]) + 1;  
     ch = (*globalString-1);     /** take the terminal characters */ 
    } 

    freeMemory(&arrayOfStrings,ROWS); 

} 

où freeMemory est:

void freeMemory(char ***matrix, int size){ 
    int i; 

    for(i = 0; i < size; i++) free((*matrix)[i]); 

    free(*matrix); 

    *matrix = NULL; 
} 

Après avoir terminé mon application, je cours avec valgrind pour rechercher des fuites de mémoire (la première fois que j'utilise valgrind).

Et je reçois l'erreur suivante:

Finding Invalid Pointer Use With Valgrind 

    ==25012== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
    ==25012== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
    ==25012== Command: dist/Debug/GNU-MacOSX/app 
    ==25012== 
    ==25012== Invalid read of size 8 
    ==25012== at 0x406445: f (Data.c:24) 
    ==25012== by 0x400BE3: main (main.c:27) 

Je ne sais pas ce que je suis absent parce que la fonction getArrayOfStrings me semble parfaitement bien (enfin je aurais pu utiliser un seul malloc, mais ce qui est un autre problème).


EDIT.

La ligne qui valgrind indique est celui-f (donnees.c: 24):

char **aux = malloc(rows * sizeof(char*)); 
+3

Quoi 'freeMemory'? – chris

+2

Comment utilisez-vous 'arrayOfStrings'? – md5

+3

Qu'y a-t-il à la ligne 24 dans Data.c, et à la ligne 27 dans main.c? –

Répondre

2

Dans mon expérience avec valgrind, il montre exactement ont été l'accès illégal est fait. Cependant, il semble que votre sortie n'affiche que le pointeur lié à l'accès illégal et où il est alloué.

Cela signifie que nous pouvons regarder la mauvaise ligne de code.

regardant de plus près votre boucle while:

while(ch != '.' && sscanf (globalString,"%[^,|.]s", arrayOfStrings[i]) > 0)  
{ 
    globalString += strlen(arrayOfStrings[i++]) + 1;  
    ch = (*globalString-1);     /** take the terminal characters */ 
} 

Si pour une raison quelconque, sur la dernière ligne ch ne égale . un accès illégal sera fait dans arrayOfStrings[rows]. L'allocation de lignes + 1 est une solution de contournement. Le contenu est inconnu et il y a des chances qu'il n'y ait pas . là, rendant la condition while évaluée à false sans accès illégal.

Je suggère soit en vous assurant un . est présent sur l'itération finale ou y compris quelque chose comme i < ROWS dans votre état tout

+1

Bon endroit - ma «réponse» est en effet une solution de contournement - plus une tentative de comprendre le problème que je ne pouvais pas obtenir parfaitement dans un commentaire. Je l'ai supprimé car il n'a rien ajouté à la question. –