8
votes

Quand devrais-je utiliser gratuitement () en C?

Le code fonctionne comme il est censé, bien que cela ne libère jamais la mémoire allouée par Malloc () .

J'ai essayé de libérer la mémoire dans n'importe quel endroit que je peux, mais peu importe Où je le fais, il brise le programme. Spécifiquement, je reçois une "double erreur de libre ou de corruption". C'est plus une question sur ce que gratuit () et masloc () réellement faire? Tous les problèmes avec libre sont dans la principale: xxx


9 commentaires

Il n'y a aucune raison de copier fichier_to_open hors argv , vous pouvez simplement utiliser utiliser argv .


Curieux de incoming_string = csestrcpy2 (incoming_string); est-ce juste une fonction de copie de chaîne?


En outre, MALLOC (STRLEN (STR + 1)); est presque certainement faux. Vous vouliez probablement dire malloc (strlen (str) +1); . (Et beaucoup de gens, y compris de moi, recommandent d'omettre les pointeurs de Cast - Void * seront implicitement convertis, et cela peut entraîner des problèmes potentiels si vous le convertissez explicitement en mauvais type.)


csestrCopy2 (entrant_string); est une méthode de copie de chaîne qui renvoie une chaîne garantie d'avoir un '/ 0' à la fin de la ligne ....


Veuillez afficher tout le code de votre fonction CsestrCopy2 car, à en juger par ce que vous avez posté dans les commentaires, cela fait partie de votre problème.


J'ai récemment édité le code pour refléter un changement que j'ai fait dessus! Le nombre Times Malloc () est dans le code a été réduit à un ... Je voudrais remercier tous ceux qui m'ont aidé!


J'ai aussi ajouté le code Csestrcpy aussi


* Remarque C Strcpy est une fonction d'un autre fichier ....


Je vois la capture 22 d'essayer de libérer la mémoire et de revenir de la fonction CsestrcPy2 où vous ne pouvez pas accéder à la Var à l'extérieur de la fonction de la fonction! Peut-être utiliser un VaR global qui peut servir de tampon réutilisable pour cette fonction? Ensuite, cela peut être libre dans n'importe quelle portée.


7 Réponses :


17
votes

En général, il vous suffit de libérer la mémoire qui vous a été réservée de manière dynamique. Cela signifie que si vous avez une déclaration comme celle-ci:

char* csestrcpy2(char* src){
    int i = 0;
    char *dest;
    char t;
    dest = (char*) malloc(MAX_LINE); /*<<- This allocates memory that has to be freed*/
    while( src[i] != '\0'){
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0';
    //printf("length:%i\n",i);
    free(dest);                  /* This frees the memory, but you return a pointer */
    return dest;                 /* to this memory. this is invalid.                */
}


5 commentaires

essayé de libérer la mémoire où vous avez dit et obtenu le: gratuit (): Pointeur non valide: 0xb76f5000 Peut-être que cela n'est pas insuffisant


Aussi, vous êtes correct à propos de la lecture in ... Je dois lire un fichier, puis stockez chaque ligne de lecture sous la forme d'une chaîne terminée NULL correctement tarifée dans une gamme de chaînes ... cela fonctionne réellement bien ... puis-je libérer la mémoire allouée pour ce tableau si je veux lire la matrice plus tard? Si je libère, puis-je quand même lire le tableau? Combien de mémoire puis-je Malloc () avant que mon programme ne soit mort?


Ce n'est pas la syntaxe pour gratuit .


whoops ... je venais de travailler récemment avec C ++ et confus libre (PTR); avec Supprimer PTR;


Que va-t-il se passer si j'appelle Call Free () sur une variable non créée avec Malloc (), par exemple, si je reçois un pointeur sur une structure et que j'appelle libres () à ce sujet, mon programme se bloque ou est-il correct?



0
votes

En règle générale, pour chaque MALLOC Il devrait y avoir un correspondant . Vous ne pouvez cependant pas gratuit quelque chose deux fois (comme vous l'avez remarqué maintenant). Je ne vois pas d'appels à GRATUIT dans votre code, il est donc impossible de dire où se trouve votre problème, mais j'ai tout de suite remarqué que vous MALLOC Certaines mémoire et attribuez-la à readline à l'intérieur d'une boucle, mais vous n'appelez pas gratuit sur readline à la fin de la boucle, vous allez donc une mémoire de la mémoire .


2 commentaires

Si je tiens à la fin de la boucle, le programme meurt ... Si je le libère après la boucle, le programme meurt ... Si je le libère à la fin du programme, le programme meurt ... il semble que Pour aller comme ceci pour une combinaison de liberté à tout moment du programme ...


@Koffee: Ce n'est certainement pas. Je voulais dire à la fin de chaque itération . Le nombre d'itérations est inconnu, vous devez donc nettoyer après vous-même. Et si vous lisez un fichier énorme? Ne concevez pas votre code pour ne travailler que dans les conditions les plus triviales, et vous devriez avoir l'habitude d'écrire du code correct de toute façon.



0
votes

penser à masloc et gratuit comme "commencez" et "fin". Chaque fois que vous appelez masloc , faites ce dont vous avez besoin pour et une fois que vous avez terminé, appelez toujours gratuit . Assurez-vous de le libérer une seule fois, une erreur double libres est une erreur d'exécution.

Si vous perdez en quelque sorte la valeur renvoyée par MALLOC (oui, c'est ce qui se passe avec votre code), vous avez une fuite de mémoire (et les portes de l'enfer ouvert, Yada Yada).

Pour ré-isterer: GRATUIT, quel que soit le retour de MALLOC (sauf null).


7 commentaires

Comment puis-je tuer la fuite de mémoire? ou au moins découvrir où c'était?


Vous ne pouvez pas «tuer» une fuite de mémoire, cela se produit lorsque votre programme se termine sans libérer la mémoire qu'il attribue. La plupart des systèmes d'exploitation gardent une trace de la mémoire allouée et gratuites, mais il n'y a aucune garantie. Vous devriez redémarrer votre système d'exploitation pour récupérer la mémoire. Vous compilez votre programme avec le support de débogage activé (-g in GCC), puis utilisez un débogueur tel que GDB ou Valgrind. Valgrind a même un outil appelé Memcheck qui montre une liste de mémoires qui ont été allouées (et où)


Impressionnant merci, j'ai également trouvé un moyen de réécrire un code qui n'a besoin que d'un malloc () ... J'apprécie toute votre aide!


@Nalin: Désolé, mais c'est incorrect. Le système d'exploitation reste en effet une trace de la mémoire allouée à un programme particulier. Cependant, lorsque le programme quitte, le système d'exploitation peut et récupère toute cette mémoire. Le dernier système d'exploitation qui a fait pas le faire, IIRC était Windows 98 (c'est pourquoi il avait besoin de redémarrer aussi souvent).


En fait, il est parfaitement légal de gratuit () un pointeur NULL (par exemple, renvoyé par Malloc dans votre dernière phrase). Le LIBC ne fera que rien, comme spécifié dans la norme. Cependant, certaines directives de codage peuvent se plaindre de le faire, car elle peut montrer que le programmeur n'a aucune idée claire de ce qui se passe avec les blocs alloués et qu'il existe des fuites de mémoire possibles ailleurs.


Je pensais que c'était juste Supprimer . Intéressant.


@Chris: Merci pour les informations. C'est ce que je voulais dire par des systèmes d'exploitation modernes. Mais la plupart des systèmes embarqués ne garantissent pas cela. C'est pourquoi je l'ai mentionné. De toute façon, c'est une mauvaise pratique de programmation de laisser des fuites de mémoire dans votre programme. :)



0
votes
        i++;
        j++;
        /// free here
        free(readline);
    }
    count++;

}
printf("current word count: %i", word_count);

//free here as well
for(int k = 0; k < count_number_of_lines; k++)
{
    free(strings_array[count_number_of_lines]);
}

return 0;
}
This should work.In general - any memory allocated dynamically - using calloc/malloc/realloc needs to be freed using free() before the pointer goes out of scope.If you allocate memory using 'new' then you need to free it using 'delete'.

3 commentaires

essayé les deux et ils me donnent tous deux un double libre ou une corruption (en haut): 0x088113C8


Ont édité le post. Je suis désolé, le libre devrait être juste après les itérateurs, avant le} et non après. aussi Strings_array [Nombre_Number_of_Lines] = (char *) MALLOC (SHLEN (à venir_string + 1)); devrait être strings_array [count_number_of_lines] = (Char *) Malloc (Strlen (dans Fille_String) +1)); puis essayez de le libérer comme indiqué ci-dessus - il devrait fonctionner


Vous avez écrit gratuitement (DEST) et vous le retournez! Cela ne renvoie pas une chaîne. Vous n'avez pas besoin de libérer la mémoire là-bas. Si vous enlevez cela, puis libérez-le à la fin, cela devrait fonctionner correctement.



0
votes

Cette ligne:

strings_array[count_number_of_lines]=(char*)malloc(strlen(incoming_string+1));


2 commentaires

Je ne peux pas retirer cette ligne ou la gamme de chaînes ne se remplit jamais, alors que j'essaie d'accéder à la gamme de chaînes plus tard, même pour l'imprimer, cela me donne un tableau de rien?


Aussi, j'ai essayé d'ajouter ça gratuitement et de recevoir: double libre ou corruption (haut): 0x088113C8 et le programme cassé ...



6
votes

Il faut être un appel à gratuit () pour chaque appel réussi à masloc () . .

qui ne signifie pas nécessairement signifie que vous devez avoir un nombre égal de MALLOC () et gratuit () appels dans votre code; Cela signifie que pour chaque MALLOC () L'appel est exécuté lorsque votre programme est exécuté, vous devez appeler gratuit () , en passant la valeur du pointeur que vous avez obtenu à partir de MALLOC ( ) . malloc () alloue la mémoire; gratuit () indique au système que vous avez terminé avec la mémoire allouée.

(vous pouvez presque certainement vous échapper sans libérer () ING de mémoire allouée lorsque votre programme se termine, car il sera récupéré par le système d'exploitation, mais de style et de bonnes pratiques Vous devriez toujours correspondre à masloc () s avec gratuit () s.)

Je ignore calloc () et realloc () appels.


2 commentaires

Pourriez-vous décrire les scénarios où l'utilisation de gratuit () est un must absolu? Depuis que le système d'exploitation le gère, pourquoi quelqu'un va-t-il jamais utiliser (en dehors de la "bonne pratique de programmation")?


@Vikasgoel: Considérez un programme qui boucle indéfiniment, allouant la mémoire sur chaque itération. Si cela ne libère pas sa mémoire allouée, elle s'épuisera rapidement.



3
votes

Allocation de mémoire dynamique (MALLOC) attribue un bloc de mémoire de taille demandée et renvoie un pointeur au début de ce bloc.Sait que nous avons pris ce bloc de la mémoire de sorte que c'est une bonne pratique pour le ramener à la mémoire après la fin de la mémoire. Tâche.

À titre de réponse de votre question, vous pouvez toujours appeler la fonction de sécurité, vous pouvez appeler une fonction libre avant de revenir. xxx


0 commentaires