2017-10-14 6 views
0

Mon code fonctionne correctement jusqu'à ce que j'essaie de libérer la mémoire allouée. J'ai malloc édité le pointeur files, et plus tard j'ai utilisé realloc pour augmenter la taille. Mais alors il me donne une erreur de pointeur invalide lorsque j'essaie de libérer la mémoire, je ne sais pas pourquoi.Impossible de libérer la mémoire allouée par Realloc dans C

char *files = malloc(1); 
char *temp = strdup(argv[i]); 
strcat(temp, "/"); 
strcat(temp, dp->d_name); 
DIR *child_dir; 
child_dir = opendir (temp); 

if (child_dir == NULL) { 
    files = realloc(files, strlen(dp->d_name)+1); 
    strcat(files, dp->d_name); 
    strcat(files, "/"); 
} else { 
    struct dirent *child_dp; 
    while ((child_dp = readdir (child_dir)) != NULL) { 
     if (!strcmp(child_dp->d_name, ".") 
      || !strcmp(child_dp->d_name, "..")) 
       continue; 

     files = realloc(files, strlen(child_dp->d_name) + 1); 
     strcat(files, child_dp->d_name); 
     strcat(files, "/"); 
    } 
} 
close(fd[0]); 
int n = write(fd[1], files, strlen(files)); 
free(temp); // free 
free(files); // free 
temp = NULL; 
files = NULL; 
return; 

C'est l'erreur que je reçois,

======= Backtrace: ========= 
/lib64/libc.so.6(+0x721af)[0x7fa2e697c1af] 
/lib64/libc.so.6(+0x77706)[0x7fa2e6981706] 
/lib64/libc.so.6(+0x78453)[0x7fa2e6982453] 
./myfind[0x40110c] 
./myfind[0x400b02] 
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fa2e692a6e5] 
./myfind[0x400a09] 
======= Memory map: ======== 

Note: Si je lance le même code sans libérer d'espace mémoire, il fonctionne très bien. Ce qui signifie que les pointeurs pointent vers l'emplacement correct dans la mémoire.

+2

Vous provoquez un comportement indéfini lorsque vous faites 'strcat (temp,"/");'. 'temp' est seulement assez grand pour la chaîne' argv [i] 'que vous avez copiée, il n'a pas de place pour vous concaténer des chaînes supplémentaires. – Barmar

Répondre

2

Vous corrompant votre tas avec ce code:

char *temp = strdup(argv[i]); 
strcat(temp, "/"); 
strcat(temp, dp->d_name); 

strdup ne consacre que suffisamment d'espace pour la chaîne, il est la duplication, mais vous concaténer alors plus sur la fin sans réaffectant pour faire de la place.

Vous n'êtes pas non plus laisser place à la terminaison NUL lorsque vous reallocfiles dans l'état if, bien que dans la plupart des cas, vous sortir avec ce que (vous devez allouer le montant correct cependant).

Enfin, dans la boucle while du else cas, chaque realloc est seulement allouer suffisamment pour les choses que vous ajoutez, mais ne pas laisser d'espace pour ce qui existe déjà (et encore, pas d'espace est laissé pour la terminaison NUL) . L'abus répété est garanti tas de corruption après un certain temps.

+1

* "dans la plupart des cas, vous vous en tirerez" *, je ne suis pas sûr que cela ne laisse pas la mauvaise impression ... peut-être que le parenthetic devrait lire (* "si vous ne parvenez pas à allouer correctement la mémoire - vous devriez être abattu! "*), ou peut-être juste *" - résultats de comportement indéterminé "*':) ' –

+0

@ DavidC.Rankin: Oui, je signale juste qu'il y a des erreurs qui souvent ne font pas provoquer des symptômes sur certains ou tous les compilateurs/systèmes, donc "ça marche" ne suffit pas pour dire que le code est correct. – ShadowRanger

+0

Oui, j'ai compris le point crucial de ce que vous disiez, ça m'a tout simplement frappé un peu bizarre/humoristique ce vendredi soir (donc le ':)' –