Quand dois-je utiliser free() en C?
Le code fonctionne comme il est censé le faire, si elle ne libère la mémoire allouée par malloc()
.
J'ai essayé de libérer de la mémoire, en quelque lieu que je peux, mais peu importe où je le fais, il se casse le programme. Plus précisément, je reçois un "double gratuit ou erreur de corruption." C'est plus une question de savoir ce que free()
et malloc()
faire réellement? Tous les problèmes avec free sont dans la main:
int main(int argc, char *argv[]){
if(argc!=2){
exit(1);
}
printf("CSA WC version 1.0\n\n");
int length = strlen(argv[argc-1]);
char file_to_open[length];
strcpy(file_to_open, argv[argc-1]);
//printf("filename:%s\n",file_to_open);
//create counters for output
int count_number_of_lines = 0;
int count_number_of_words = 0;
int count_number_of_characters = 0;
//create int size of default array size
int current_array_size = pre_read(file_to_open);
//printf("number of lines: %i\n",current_array_size);
//create string array of default size
char *strings_array[current_array_size];
//create a pointer to catch incoming strings
char *incoming_string=NULL;
int done=0;
while(done==0){
incoming_string=get_line_from_file(file_to_open, count_number_of_lines);
if(incoming_string!=NULL){
incoming_string=csestrcpy2(incoming_string);
//printf("incoming line: %s\n",incoming_string);
strings_array[count_number_of_lines]=(char*)malloc(strlen(incoming_string+1));
strings_array[count_number_of_lines]=csestrcpy2(incoming_string);
//printf("added to array:%s\n",strings_array[count_number_of_lines]);
count_number_of_lines++;
count_number_of_characters=(count_number_of_characters+(strlen(incoming_string)-1));
}
else{
done=1;
}
}
//all data is stored in a properly sized array
//count all words in array
int count=0;
int word_count=0;
char *readline;
while(count<current_array_size){
readline = csestrcpy2(strings_array[count]);
printf("line being checked: %s", readline);
int i=0;
int j=1;
while( j< strlen(readline)+1 ){
if(strcmp(readline,"\n")!=0){
if( (readline[i] == ' ') && (readline[j] != ' ') ){
word_count++;
}
if( (readline[i] != ' ') && (readline[j] == '\n') ){
word_count++;
}
}
i++;
j++;
}
count++;
}
printf("current word count: %i", word_count);
return 0;
}
char* csestrcpy2(char* src){
int i = 0;
char *dest;
char t;
dest = (char*) malloc(MAX_LINE);
while( src[i] != '\0'){
dest[i] = src[i];
i++;
}
dest[i] = '\0';
//printf("length:%i\n",i);
free(dest);
return dest;
}
- Il n'y a pas de raison de copie
file_to_open
deargv
, vous pouvez simplement utiliserargv
. - Curieux de savoir
incoming_string=csestrcpy2(incoming_string);
Est-ce juste une chaîne de caractères la fonction de copie? - Aussi,
malloc(strlen(str+1));
est presque certainement faux. Vous signifiait probablementmalloc(strlen(str)+1);
. (Et beaucoup de gens, moi y compris, de recommander l'omission de la fonte devoid *
pointeurs être implicitement converti, et il peut causer des problèmes potentiels si vous convertir explicitement le mauvais type.) - csestrcopy2(incoming_string); une copie de chaîne de méthode qui renvoie une chaîne qui est la garantie d'avoir un '/0' à la fin de la ligne....
- Merci de poster le code complet de votre csestrcopy2 fonction, car, à en juger par ce que vous avez posté dans les commentaires, c'est une partie de votre problème.
- Récemment, j'ai modifié le code afin de refléter un changement que j'ai fait sur elle! le nombre de fois malloc() est dans le code a été réduit à un seul... je tiens à remercier tous ceux qui m'aident!
- J'ai aussi ajouté le csestrcpy code ainsi
- *note csestrcpy est une fonction à partir d'un autre fichier....
Vous devez vous connecter pour publier un commentaire.
En général, vous n'avez qu'à libérer de la mémoire qui a été réservé pour vous de façon dynamique. Cela signifie que si vous avez un énoncé comme ceci:
que vous avez besoin de libérer la mémoire qui a été allouée (réservé) par malloc.
si vous n'êtes pas certain de gratuit que de le libérer à la fin du programme, en utilisant free;
Dans votre fichier, il semble comme il y aura de la mémoire allouée à chaque fois qu'il y a une nouvelle ligne dans le fichier de vous lire (dans le
while(done==0)
boucle). donc, à chaque fois après leif
dans la boucle que vous avez à libérer la mémoire qui a été utilisée par la variable.En outre, vous devez libérer la mémoire qui a été allouée par la readline variable. Mais comme il a été souligné avant de vous peut avoir une fuite de mémoire là.
Espère que cette aide.
edit: Ok - j'avais déjà demandé sur le
csestrcpy
fonction. Permet d'avoir un oeil à cette fonction:Ce que vous pouvez, toutefois, le libre est la src pointeur dans cette fonction. mais rappelez-vous: le pointeur ne peut pas détenir des informations après le sous-jacent est libéré de la mémoire! Il a juste des points à un endroit de la mémoire où il ne faut pas écrire ou de lire plus.
En outre la fonction copys la chaîne, tant qu'il n'y a pas de '\0'. Qu'advient-il si il n'y a pas de terminator? La fonction garde sur la copie de la mémoire les adresses où il ne devrait pas!
vous ne devriez pas utiliser cette fonction 😉
free
.Il doit y avoir un appel à
free()
pour chaque appel réussi àmalloc()
.Qui n'a pas nécessairement dire que vous devez avoir un nombre égal de
malloc()
etfree()
appels dans votre code, cela signifie que pour chaquemalloc()
appel qui est exécutée lorsque votre programme s'exécute, vous devez appelerfree()
, en lui passant le pointeur de la valeur que vous avez obtenu d'malloc()
.malloc()
alloue de la mémoire;free()
indique au système que vous avez terminé avec la mémoire allouée.(Vous pouvez presque certainement vous en sortir avec pas
free()ing
mémoire allouée lorsque votre programme se termine, car il sera récupéré par le système d'exploitation, mais seulement comme une question de style et de bonnes pratiques que vous devriez toujours correspondre àmalloc()
s avecfree()
s.)Je suis ignorant
calloc()
etrealloc()
appels.Allocation dynamique de la mémoire (malloc) alloue un bloc de mémoire de taille demandée, et renvoie un pointeur sur le début de ce bloc.Depuis que nous avons pris ce bloc de mémoire de sorte que son une bonne pratique pour revenir à ce retour de mémoire après l'achèvement de la tâche.
Maintenant pour répondre à votre question , À toujours être sur le côté sûr, vous pouvez appeler libre de la fonction avant de faire retour.
En règle générale, pour chaque
malloc
il devrait y avoir un correspondantfree
. Cependant on ne peut pasfree
deux fois la même chose (comme vous l'avez remarqué). Je ne vois pas tous les appels àfree
dans votre code, il est donc impossible de dire où votre problème, mais j'ai remarqué tout de suite que vousmalloc
de la mémoire et de l'attribuer àreadline
à l'intérieur d'une boucle, mais vous n'appelez pasfree
surreadline
à la fin de la boucle, de sorte que vous êtes une fuite de mémoire là.Pense
malloc
etfree
comme "début" et "fin". TOUTES les fois que vous appelezmalloc
, faire ce que vous devez et une fois que vous avez terminé, toujours faire appel àfree
. Assurez-vous de ne le libérer une fois, double-libre est une erreur d'exécution.Si vous en quelque sorte perdre de la valeur retournée par
malloc
(oui, c'est ce qui se passe avec votre code), alors vous avez une fuite de mémoire (et les portes de l'enfer s'ouvrir, yada yada).De ré-itérer: gratuit quelque malloc renvoie (à l'exception de la valeur null).
free()
un pointeur NULL (par exemple, retourné par malloc dans votre dernière phrase). La libc ne rien faire, comme spécifié dans la norme. Toutefois, certaines règles de codage peuvent se plaindre à ce sujet, car il peut montrer que le programmeur n'a pas d'idée claire de ce qui se passe avec les blocs alloués et qu'il est possible les fuites de mémoire d'ailleurs.delete
. Intéressant.Cette ligne:
est remplacée par la ligne à côté de lui, de sorte qu'il peut être supprimé.
Vous devez également ajouter
free(readline)
aprèscount++
dans la dernière boucle pour libérer de la mémoire créé par malloc.Cela devrait fonctionner.
En général, à toute la mémoire allouée dynamiquement à l'aide de calloc/malloc/realloc a besoin d'être libérée à l'aide de free() avant le pointeur est hors de portée.
Si vous allouer de la mémoire à l'aide de "nouveau", puis vous avez besoin de l'aide de 'supprimer'.