85 votes

Lorsque vous quittez une application C, la mémoire malloc-ed est-elle automatiquement libérée?

Disons que j'ai le code C suivant:

 int main () {
  int *p = malloc(10 * sizeof *p);
  *p = 42;
  return 0;  //Exiting without freeing the allocated memory
}
 

Lorsque je compile et exécute ce programme C, c'est-à-dire après avoir alloué de l'espace en mémoire, la mémoire que j'ai allouée sera-t-elle toujours allouée (c'est-à-dire occupant essentiellement de l'espace) après avoir quitté l'application et le processus terminé?

104voto

Yacoby Points 29771

Il dépend du système d'exploitation. La majorité des modernes (et de tous les principaux systèmes d'exploitation permettra de libérer de la mémoire ne sont pas libérés par le programme quand il se termine.

En s'appuyant sur ce qui est une mauvaise pratique, il est préférable de libérer explicitement. Le problème n'est pas juste que votre code est mauvais. Vous pouvez décider vous souhaitez intégrer à votre programme de petite taille dans un plus long cours d'exécution. Puis un peu plus tard que vous avez à passer des heures à traquer les fuites de mémoire.
En s'appuyant sur une caractéristique d'un système d'exploitation aussi rend le code moins portable.

43voto

Kevin Reid Points 8806

En général, moderne à usage général systèmes d'exploitation ne se nettoyer après le processus terminés. Cela est nécessaire parce que l'alternative est que le système de perdre des ressources au fil du temps et nécessitent le redémarrage en raison de programmes qui sont mal écrits, ou tout simplement d'rarement survenant de bugs que la fuite des ressources.

Avoir votre programme explicitement libre de ses ressources de toute façon peut être une bonne pratique pour diverses raisons, y compris, de manière à permettre l'intégration dans des programmes plus larges, comme d'autres réponses ont couvert.

Cependant, ici, c'est une raison pour ignorer la libération de la mémoire: efficace d'arrêt. Par exemple, supposons que votre application contient un grand cache en mémoire. Si quand il sort, il traverse l'intégralité du cache de la structure et permet de se libérer d'une seule pièce à la fois, qui ne sert à rien et le gaspillage de ressources. En particulier, considérons le cas où les pages de mémoire contenant le cache ont été échangés sur le disque par le système d'exploitation; par la marche de la structure et en la libérant, vous êtes en apportant toutes ces pages en arrière dans la mémoire de tous à la fois, de perdre beaucoup de temps et d'énergie pour aucun bénéfice réel, et peut-être même causer d'autres programmes sur le système pour obtenir échangé!

Comme un exemple similaire, il y a des serveurs à haute performance que de travail par la création d'un processus pour chaque demande, que de l'avoir sortie en fait; par ce moyen, ils n'ont même pas de trace de la mémoire de l'allocation, et ne font pas du tout de libérer ou de collecte des ordures à tous, depuis tout s'évanouit dans le système d'exploitation libre de la mémoire à la fin du processus. (Le même genre de chose qui peut être fait à l'intérieur d'un processus à l'aide d'un personnalisé programme d'allocation de mémoire, mais nécessite très prudent de programmation.)

7voto

Wes Miller Points 972

Mes excuses pour l'affichage si longtemps après le dernier post de ce fil.

Un point supplémentaire. Pas tous les programmes, il est gracieux sorties. Les accidents et ctrl-C, etc. va provoquer un programme de sortie incontrôlée des manières. Si votre système d'exploitation n'est pas libre de votre tas, nettoyer votre tapis, supprimer des variables statiques, etc, finira par le plantage de votre système de fuites de mémoire ou pour le pire.

Intéressant côté de cela, les accidents/pauses dans Ubuntu, et je soupçonne que tous les autres Systèmes d'exploitation modernes, ont des problèmes avec les "manipulés" des ressources. Sockets, des fichiers, des périphériques, etc. peut rester "ouvert" lorsqu'un programme se termine ou plantages. C'est aussi une bonne pratique pour fermer quoi que ce soit avec une "poignée" ou "descripteur" dans le cadre de votre activité de nettoyage avant gracieux sortie.

Je suis actuellement à l'élaboration d'un programme qui utilise des sockets fortement. Quand je suis coincé dans la gueule que j'ai à ctrl-c en dehors de ça, donc, l'échouage de mes orbites. J'ai ajouté un std::vector pour collecter une liste de tous les ouverts sockets et une sigaction gestionnaire de captures sigint et sigterm. Le gestionnaire parcourt la liste et ferme les sockets. J'ai l'intention de faire un similaires routine de nettoyage pour une utilisation avant de lancer qui conduira à la résiliation anticipée.

Quelqu'un soin de commenter cette conception?

6voto

Ben Zotto Points 32105

Ce qui se passe ici (dans un système d'exploitation moderne), c'est que votre programme s'exécute à l'intérieur de son propre "processus". C'est un système d'exploitation de l'entité qui est doté de son propre espace d'adressage, les descripteurs de fichier, etc. Votre malloc des appels sont d'allouer de la mémoire dans le "tas", ou de la mémoire non allouée pages qui sont attribuées à votre processus.

Lorsque votre programme se termine, comme dans cet exemple, toutes les ressources affectées à votre processus sont simplement recyclés/démolie par le système d'exploitation. Dans le cas de la mémoire, toutes les pages de mémoire qui vous sont assignées sont simplement marqués comme "libre" et recyclées pour l'utilisation d'autres procédés. Les Pages sont d'un niveau inférieur concept que ce que malloc poignées-- en conséquence, les spécificités de malloc/free sont tout simplement lavé comme toute chose est nettoyé.

C'est l'équivalent moral de l', lorsque vous avez fini d'utiliser votre ordinateur portable et souhaitez donner à un ami, vous n'avez pas pris la peine de supprimer individuellement chaque fichier. Vous venez de formater le disque dur.

Tout cela dit, comme tous les autres answerers sont notant, en s'appuyant sur ce n'est pas une bonne pratique:

  1. Vous devez toujours être à la programmation de prendre soin de ressources, et en C, cela signifie que la mémoire ainsi. Vous risquez de vous retrouver à l'incorporation de votre code dans une bibliothèque, ou il peut finir beaucoup plus long que prévu.
  2. Certains systèmes d'exploitation (les plus anciens et peut-être que certains modernes, ceux intégrés) ne peut pas maintenir ce difficile processus de limites, et vos allocations peuvent affecter d'autres espaces d'adressage.

4voto

Mark Wilkins Points 29291

Oui. Le système d'exploitation nettoie les ressources. Eh bien ... les anciennes versions de NetWare ne le faisaient pas.

Edit: Comme San Jacinto l’a fait remarquer, il existe certainement des systèmes (mis à part NetWare) qui ne le font pas. Même dans les programmes jetables, j'essaie de prendre l'habitude de libérer toutes les ressources simplement pour maintenir cette habitude.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X