2011-07-24 5 views
0

Cette question est nulle et non avenue! Je ne libérais pas correctement les étudiants! J'accepterai la réponse qui me l'a révélé aussi vite que je suis autorisé! Je suis nouveau à C et je pratique malloc. Dans la grande portée, j'écris une bibliothèque de liste liée; Cette fonction create_student fait partie des nombreuses fonctions que je vais utiliser pour tester ma bibliothèque de listes chaînées. Le problème est ... Je cours valgrind et appelle cette fonction et il indique qu'il y a plusieurs fuites de mémoire provoquées par ce premier malloc. Tout semble solide, le meilleur à ma connaissance:strlen et malloc: C fuites de mémoire

typedef struct Student 
{ 
     char* first_name; /* This will be malloc'd!*/ 
    char* last_name; /* This will also be malloc'd */ 
    int grade; 
    long id; 
} Student; 


Student* create_student(const char* first_name, const char* last_name, int grade, long gtid) 
{ 

     /* First allocate a student on the heap */ 
     Student *newStudentp = (malloc(sizeof(Student))); 


    /* Allocate enough space for the first and last names */ 
    newStudentp -> last_name = (malloc(strlen(last_name))); 
    newStudentp -> first_name = (malloc(strlen(first_name))); 



     // AND copy the first and last name to the first and last name fields in the struct 
    strncpy(newStudentp -> first_name, first_name, strlen(first_name)); 
    strncpy(newStudentp -> last_name, last_name, strlen(last_name)); 



     /* Set the grade and id */ 
    newStudentp -> grade = grade; 
    newStudentp -> id = id; 

     */ 
    return newStudentp; 
} 

Mes messages d'erreur de valgrind (il y en a plusieurs) ressemblent à ceci:

==4285== 9 bytes in 1 blocks are definitely lost in loss record 8 of 8 
==4285== at 0x4025BD3: malloc (vg_replace_malloc.c:236) 
==4285== by 0x804855B: create_student (test.c:24) 
==4285== by 0x8048748: main (test.c:109) 

ligne 24 est le

newStudentp -> last_name = (malloc(strlen(last_name))); 

ligne .

Y a-t-il une mauvaise utilisation fondamentale de strlen par moi qui cause une erreur?

+2

Comment libérez-vous vos structures d'étudiant? – Mat

+2

Notez que 'strlen' renvoie la longueur de la chaîne _not_, y compris le caractère final '' \ 0''. – Hasturkun

+1

Votre 'malloc' pour' last_name' devrait allouer 'strlen (last_name) + 1' caractères afin d'inclure de l'espace pour le '\ 0' (même pour' first_name') – jonsca

Répondre

1

Il y a quelques problèmes ici:

newStudentp -> last_name = (malloc(strlen(last_name))); 
    newStudentp -> first_name = (malloc(strlen(first_name))); 

strlen ne donne que la longueur jusqu'à, mais sans compter le '\0'. Mais cela doit être stocké aussi, donc vous devriez utiliser strlen(last_name) + 1 dans les deux cas. De plus, votre strncpy() devrait mieux être fait en utilisant la taille du tampon alloué et non de la chaîne source, de sorte que vous pouvez éviter d'écrire au-delà de la limite supérieure du tableau. Mais puisque vous avez déjà utilisé malloc(strlen(...) + 1), vous pouvez simplement utiliser strcpy() ici.

+1

strncpy() est rarement la bonne fonction. Contrairement aux autres fonctions strn *(), ce n'est pas * simplement * une version "plus sûre" de strcpy(). Dans certains cas, il peut laisser le tableau cible non terminé (c'est-à-dire, pas une chaîne valide); dans d'autres, il peut perdre du temps à remplir la cible avec des caractères '\ 0' supplémentaires. –