IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Comment résoudre cette difficulté


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut Comment résoudre cette difficulté
    Bonjour,

    Il me semble que les fuites mémoires en C résultent souvent d'un retour de fonction qui ne sera pas libéré. Entre autres.

    Le compilateur du C n'y verra que du feu. Les principales applications écrites en C sont truffées de fuites de mémoire.

    En ADA c'est plus restrictif. Mais les applications en C survivent grâce à la bienveillance du système d'exploitation.

    Le langage C est ainsi englobé dans un système d'erreurs compensées avec des technologies propres à un système d'exploitation.

    On peut s'en réjouir, tout en se demandant jusqu'où ira l'erreur compensée en C ?

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Toutes les allocations non libérées ne sont pas des fuites mémoire.

    Si un programme aloue de la mémoire, qui devient inutile, et que le programme en question à encore une longue vie à vivre après que cette mémoire soit devenue inutile (je parle de quantité de traitements à faire, pas de temps), alors c'est une fuite mémoire.

    Si un programme aloue de la mémoire, qui devient inutile, mais que développeur sait que le programme va terminer peut de temps après, ce n'est pas une fuite mémoire. C'est une décision consciente qui permet d'éviter des lignes inutiles, potentiellement buggées, qui alourdiraient inutilement le code.

    En particulier, chercher en cas de terminaison anormale à libérer toute les allocations, est une erreur de débutant.

  3. #3
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par matafan Voir le message
    En particulier, chercher en cas de terminaison anormale à libérer toute les allocations, est une erreur de débutant.
    Pourquoi ?

    Bien que de nombreux systèmes libèrent effectivement ce qui a été alloué lorsqu'un programme se termine, il n'y a rien à ma connaissance qui garantisse que c'est le cas sur tous les systèmes (si tu as une référence qui garantisse que cette libération est faite, ça m'intéresse).

    Ecrire un programme portable nécessite donc de faire ces libérations.

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par matafan Voir le message
    En particulier, chercher en cas de terminaison anormale à libérer toute les allocations, est une erreur de débutant.
    Le vrai problème est 'terminaison anormale'. Si la vie d'un patient est en jeu, il n'y a pas de 'terminaison anormale', ou alors, tu as intérêt à avoir un bon avocat. Idem en avionique. Je vois mal un BSOD apparaitre sur le tableau de bord d'un Airbus A380 pendant qu'il survole Paris à 30000 pieds...

    "Veuillez mettre vos parachutes, pendant que le système tente de redémarrer..."

    Cool...

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Le vrai problème est 'terminaison anormale'. Si la vie d'un patient est en jeu, il n'y a pas de 'terminaison anormale', ou alors, tu as intérêt à avoir un bon avocat. Idem en avionique. Je vois mal un BSOD apparaitre sur le tableau de bord d'un Airbus A380 pendant qu'il survole Paris à 30000 pieds...

    "Veuillez mettre vos parachutes, pendant que le système tente de redémarrer..."

    Cool...
    Je ne suis pas d'accord, il y a des "terminaisons anormales" qui sont parfaitement justifiées et, heu... Normales. Si un fichier n'existe pas, si on n'a pas les droits, si une donnée n'est pas valide, si on arrive à court d'une ressource donnée... Les exemples que tu donnes sont très particuliers.

  6. #6
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Citation Envoyé par matafan Voir le message
    Je ne suis pas d'accord, il y a des "terminaisons anormales" qui sont parfaitement justifiées et, heu... Normales. Si un fichier n'existe pas, si on n'a pas les droits, si une donnée n'est pas valide, si on arrive à court d'une ressource donnée... Les exemples que tu donnes sont très particuliers.
    Tous ces cas de figure peuvent être anticipés et traités en conséquence! Si l'on a pas les droit sur un fichier, on en avertit l'utilisateur et le programme se termine normalement. Il y a une différence entre terminaison anormale et traitement des cas. Un programme peut très bien se terminer normalement sans avoir effectué le traitement espéré.
    Le seul cas de terminaison anormale que je peux imaginer est la terminaison pour une coupure de courant. Là d'accord, mais ce n'est plus du ressort du programmeur.

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    J'ai du mal exprimer ce que je voulais dire. Ce que je veux dire c'est que dans un programme, ce genre de problème peut survenir sur n'importe quelle opération, n'importe où dans le programme. Si tu as fais quelques allocations avant l'erreur, pas de problème, ça ne coute rien de tout nettoyer avant de quitter. Mais si ca arrive au milieu du programme, après de nombreuses allocations, il y a un point ou nettoyer avant la sortie en erreur est contre productif : il faut investire beaucoup de temps à coder des routines de nettoyage complexes, potentiellement buggées, pour finalement un résultat nul puisque qu'on quitte immédiatement après. Ne pas faire le ménage ce n'est pas faire preuve de paresse, c'est faire preuve de discernement. C'est du temps mieux investi à faire autre chose.

    dj.motte, les exemples que tu donnes sont exactement des cas où il est probablement justifié de ne pas faire le ménage. La pluspart de ces allocations sont probablement des structures de données dont le programme (kwrite ou vi) a besoin tout au long de son exécution. On ne peut donc les libérer qu'à la sortie du programme. Alors a quoi bon ? Qu'on écrive 1000 lignes de code ou 0 pour libérer tout ça, le résultat est le même. Par contre évidemment, si certaines allocations deviennent inutiles et qu'on ne s'apprète pas à terminer, il est évidemment de bon ton de libérer ces allocations.

    D'autre part j'ai l'impression que certains pensent qu'en ne libérant pas certaines allocations, l'OS a besoin de "passer derrière" et de faire le boulot à la place du programmeur. Ce n'est pas tout à fait exact, dans la mesure où l'OS n'a aucun traitement particulier à faire. Quand un programme termine l'OS libère la mémoire utilisée pour l'address space du programme, et il le fait de toute façon. Que cette mémoire soit utilisée pour le texte du programme, pour la stack, pour le heap ou pour les fichiers mappés, ça ne change rien. L'OS libère tout. Il se fout pas mal de savoir que le truc qu'il est en train de libérer, c'est le buffer que telle applis a oublié de libérer.

  8. #8
    Membre éprouvé Avatar de BainE
    Inscrit en
    Mai 2004
    Messages
    1 327
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 1 327
    Par défaut
    Bonjour,

    je demande la suppression du thread,
    le forum n'est pas la pour déballer ses frustrations.

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Bonjour,

    Concernant les fuites de mémoire en C je suis bien d'accord que la bonne gestion revient au développeur, pas au langage en lui-même.

    Ceci étant c'est tout de même surprenant qu'il y ait autant de programme en C avec ce genre de défaut, sachant que ceux qui les écrivent ne sont pas des blaireaux.

    A moins que l'outil de vérification de la mémoire soit erroné?

    Un petit exemple avec Linux, un valgrind kwrite donne :
    ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 150 from 3)
    ==8131== malloc/free: in use at exit: 477,131 bytes in 3,919 blocks.
    ==8131== malloc/free: 413,030 allocs, 409,111 frees, 14,077,488 bytes allocated.
    ==8131== For counts of detected errors, rerun with: -v
    ==8131== searching for pointers to 3,919 not-freed blocks.
    ==8131== checked 1,913,516 bytes.
    ==8131==
    ==8131== LEAK SUMMARY:
    ==8131== definitely lost: 17,743 bytes in 419 blocks.
    ==8131== possibly lost: 0 bytes in 0 blocks.
    ==8131== still reachable: 459,388 bytes in 3,500 blocks.
    ==8131== suppressed: 0 bytes in 0 blocks.
    ==8131== Rerun with --leak-check=full to see details of leaked memory.
    Visiblement il y a plus de malloc que de free. Mais bon l'OS tient.

    Un petit valgrind vi donne :
    ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 35 from 1)
    ==8268== malloc/free: in use at exit: 348,631 bytes in 10,422 blocks.
    ==8268== malloc/free: 19,081 allocs, 8,659 frees, 1,764,722 bytes allocated.
    ==8268== For counts of detected errors, rerun with: -v
    ==8268== searching for pointers to 10,422 not-freed blocks.
    ==8268== checked 876,704 bytes.
    ==8268==
    ==8268== LEAK SUMMARY:
    ==8268== definitely lost: 1,141 bytes in 5 blocks.
    ==8268== possibly lost: 7,081 bytes in 61 blocks.
    ==8268== still reachable: 340,409 bytes in 10,356 blocks.
    ==8268== suppressed: 0 bytes in 0 blocks.
    ==8268== Rerun with --leak-check=full to see details of leaked memory.

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte Voir le message
    Concernant les fuites de mémoire en C je suis bien d'accord que la bonne gestion revient au développeur, pas au langage en lui-même.
    C'est déjà un point important.
    Ceci étant c'est tout de même surprenant qu'il y ait autant de programme en C avec ce genre de défaut, sachant que ceux qui les écrivent ne sont pas des blaireaux.
    Bienvenue dans le monde réel.
    A moins que l'outil de vérification de la mémoire soit erroné?
    Ou que tu ne saches pas t'en servir... Je ne le connais pas.

    Je ne suis pas sûr que ça ait un sens de l'utiliser sur une application compilée en mode Release...

  11. #11
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 450
    Par défaut
    Autant que je sache, il n'y a pas trente-six manières d'éviter les fuites de mémoire. Soit on alloue statiquement la mémoire (à la compilation, en général dans la pile), soit on fait attention à ce que l'on fait, soit on utilise un garbage collector.

    Le C sert précisement à travailler sans filet si nécessaire. Si, pour toi, le C est un mauvais langage parce que tu estimes qu'un programmeur ne peut pas travailler suffisamment proprement pour rendre ce qu'il emprunte, ce qui est quand même un peu fort, eh ben tu redéfinis malloc() de manière à ce qu'il garde trace de tous les pointeurs qu'il a renvoyé et tu fais un atexit() pour lui faire faire automatiquement le ménage en sortant.

    Et voila, tu n'as plus besoin de l'O.S. Mâââgique ! :-)

  12. #12
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Bonjour,
    Autant que je sache, il n'y a pas trente-six manières d'éviter les fuites de mémoire. Soit on alloue statiquement la mémoire (à la compilation, en général dans la pile), soit on fait attention à ce que l'on fait, soit on utilise un garbage collector.

    Le C sert précisement à travailler sans filet si nécessaire. Si, pour toi, le C est un mauvais langage parce que tu estimes qu'un programmeur ne peut pas travailler suffisamment proprement pour rendre ce qu'il emprunte, ce qui est quand même un peu fort, eh ben tu redéfinis malloc() de manière à ce qu'il garde trace de tous les pointeurs qu'il a renvoyé et tu fais un atexit() pour lui faire faire automatiquement le ménage en sortant.

    Et voila, tu n'as plus besoin de l'O.S. Mâââgique ! :-)
    Ben si. La plupart des grandes applications en C ou même en C++ souffrent de défaillances mémoire.

    C'est le système d'exploitation qui reprend la main quand c'est possible.

    Le langage C ou moins encore le C++ passe au travers de la compilation plus exacte, comme en ADA ou à défaut PASCAL.

    La plupart des applications écrites en C souffrent de bogues en tous genres. Ce qui ne veut pas dire que le C soit un mauvais langage. Mais qu'il donne des habilités aux plus fanfarons.

    Le C c'est l'avantage moins les difficultés ?

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte Voir le message
    La plupart des grandes applications en C ou même en C++ souffrent de défaillances mémoire.
    Quel rapport avec le langage ? Le code est mal écrit (et surtout mal testé), c'est tout. Faut pas chercher plus loin. Rien de magique là-dedans...
    C'est le système d'exploitation qui reprend la main quand c'est possible.
    Et quand il n'y a pas de SE ? Et quand l'application tourne 24h/24 (serveur, routeur, base de donnée etc.)
    Le langage C ou moins encore le C++ passe au travers de la compilation plus exacte, comme en ADA ou à défaut PASCAL.
    cette phrase n'a aucun sens (Ada, Pascal)... Il n'y a aucune difficulté à provoquer des fuites mémoire en Pascal ou en Ada. Il suffit juste d'être aussi incompétent qu'en C ou en C++.
    La plupart des applications écrites en C souffrent de bogues en tous genres. Ce qui ne veut pas dire que le C soit un mauvais langage. Mais qu'il donne des habilités aux plus fanfarons.
    Qu'est-ce que ça peut bien vouloir dire ? Le C est un langage pour programmeur compétant, oui. C'est un scoop ?
    Le C c'est l'avantage moins les difficultés ?
    Incompréhensible. Quel avantage ? Quelles difficultés ?

  14. #14
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par dj.motte Voir le message
    Il me semble que les fuites mémoires en C résultent souvent d'un retour de fonction qui ne sera pas libéré. Entre autres.
    Les fuites mémoire viennent

    - soit d'une erreur de conception (rien n'a été prévu pour libérer la mémoire allouée)
    - soit d'un comportement indéfini qui corrompt le mécanisme de gestion de la mémoire allouée
    - soit d'une mauvaise utilisation des fonctions de libérations
    - soit de l'incompétence du programmeur

    Le compilateur du C n'y verra que du feu. Les principales applications écrites en C sont truffées de fuites de mémoire.
    C'est possible et c'est parce qu'elles sont mal testées. Personnellement, étant particulièrement sensible à ce problème, ayant travaillé dans le domaine du logiciel embarqué tournant 24/7, j'ai développé un outil de test portable qui me permettait de vérifier mes libération et ma consommation de bloc alloués.

    http://emmanuel-delahaye.developpez.com/clib.htm
    Module SYSALLOC

    En ADA c'est plus restrictif.
    Je ne vois pas ce qui empêcherais de faire des erreurs de libération en Ada (et non ADA. C'est un nom, comme Pascal et non un acronyme comme BASIC).

    Mais les applications en C survivent grâce à la bienveillance du système d'exploitation.
    En embarqué 24/7, c'est pas le SE qui va régler le problème, mais un code écrit correctement. Point. Mes codes étaient réputés pour leur stabilité dans le temps..

    Le langage C est ainsi englobé dans un système d'erreurs compensées avec des technologies propres à un système d'exploitation.
    Non.
    On peut s'en réjouir, tout en se demandant jusqu'où ira l'erreur compensée en C ?
    Le problème n'est pas le C mais la compétence du programmeur et les moyens qu'il se donne pour écrire du code correct. C'est tout.

    Tout le monde fait des erreurs. Ce qui est inacceptable, c'est de ne pas s'en apercevoir et donc de ne pas les corriger.

    Il est inutile de blâmer le langage.

Discussions similaires

  1. Comment résoudre cette erreur ?
    Par jmbinformatique dans le forum Odoo (ex-OpenERP)
    Réponses: 2
    Dernier message: 20/11/2013, 13h59
  2. Réponses: 0
    Dernier message: 12/05/2011, 15h51
  3. comment résoudre cette exception?merci
    Par achraf11 dans le forum Hibernate
    Réponses: 0
    Dernier message: 24/03/2010, 14h26
  4. Réponses: 5
    Dernier message: 22/01/2009, 17h19
  5. Réponses: 1
    Dernier message: 22/08/2006, 15h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo