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 :

Combattre les fuites de mémoire et les erreurs C++11


Sujet :

C++

  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    25 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : mai 2008
    Messages : 25 955
    Points : 207 576
    Points
    207 576
    Billets dans le blog
    85
    Par défaut Combattre les fuites de mémoire et les erreurs C++11
    Bonjour à tous,

    Dans cet article, traduit par Eric GERARD, vous allez apprendre comment éviter les erreurs de mémoire grâce au C++11. De plus, vous verrez l'utilisation de valgrind afin de détecter ces erreurs liées à la mémoire.

    Bonne lecture
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    décembre 2013
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2013
    Messages : 323
    Points : 429
    Points
    429
    Par défaut
    L'article n'est pas inintéressant, mais au final :
    - beaucoup d'exemples donnés sont des problèmes qui ne devrait plus avoir lieu déjà en C++03 (utilisation de new[] au lieu de vector, utilisation de pointeurs au lieu de références, variables non initialisée)
    - ce sont des exemples de problème d'utilisation des structures brutes en générale, qui sont solutionné par le RAII
    - seul l'exemple sur la tableau de taille statique à une solution spécifique en C++11 (std::array)
    - l'article parle plus de l'utilisation de valgrind et les principaux types de problèmes qu'il permet de diagnostiquer que des solutions apportées par le C++11 (il y a juste quelques lignes à la fin)
    Quand je vois la partie VIII, je me demande si l'auteur connait le RAII...
    Pour la partie IX, c'est tellement survolé que l'on peut pas dire grand chose. Sauf peut être que j'ai entendu un certain Luc dire que vector::at() est de la programmation défensive, donc pas forcement une bonne pratique (cf son blog - qu'en est-ce que le troisième article sera publié ? )

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    mai 2008
    Messages
    25 955
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : mai 2008
    Messages : 25 955
    Points : 207 576
    Points
    207 576
    Billets dans le blog
    85
    Par défaut
    Je ne le voyais pas de la sorte, mais plus :
    • le C++ permet d'utiliser les pointeurs (allocation dynamique). Cela peux aussi vous amener à faire des fuites de mémoire ;
    • voici ce que sont les fuites de mémoire ;
    • voici comment ont les détecte ;
    • voici des (quelques ?) solutions.


    D'ailleurs, le deuxième point, dans VIII, pour moi, c'est faire du RAII :
    Lorsque vous utilisez un pointeur local dans une fonction membre (qui n'est pas un attribut de la classe courante), il est hautement probable qu'une variable locale soit suffisante ;
    Mais il est possible que j'extrapole un peu

    Pour la partie XI, bah après les détails sont à trouver dans un cours C++ détaillé sur C++11, ou encore, vous les connaissez déjà
    Cet article est plus pour les débutants, qui ne connaissent pas spécialement les fuites de mémoire.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : septembre 2007
    Messages : 71
    Points : 114
    Points
    114
    Par défaut
    Citation Envoyé par mintho carmo Voir le message
    L'article n'est pas inintéressant, mais au final :
    - beaucoup d'exemples donnés sont des problèmes qui ne devrait plus avoir lieu déjà en C++03 (utilisation de new[] au lieu de vector, utilisation de pointeurs au lieu de références, variables non initialisée)
    - ce sont des exemples de problème d'utilisation des structures brutes en générale, qui sont solutionné par le RAII
    - seul l'exemple sur la tableau de taille statique à une solution spécifique en C++11 (std::array)
    - l'article parle plus de l'utilisation de valgrind et les principaux types de problèmes qu'il permet de diagnostiquer que des solutions apportées par le C++11 (il y a juste quelques lignes à la fin)
    Quand je vois la partie VIII, je me demande si l'auteur connait le RAII...
    Pour la partie IX, c'est tellement survolé que l'on peut pas dire grand chose. Sauf peut être que j'ai entendu un certain Luc dire que vector::at() est de la programmation défensive, donc pas forcement une bonne pratique (cf son blog - qu'en est-ce que le troisième article sera publié ? )
    Tout à fait d'accord avec toi. Quand j'ai vu que l'auteur prétend combattre les erreurs mémoie en c++11 en parlant de valgrind, et en prenant comme exemple du code avec des pointeurs nu, des new et des delete, je n'ai eu qu'une envie : lui mettre des baffes! Après, c'est vrai qu'il en parle à la fin, mais c'est fait de façon tellement annectodique. Le minimun aurait été de reprendre les exemples du dessus et de montrer comment utiliser des smart pointeurs pour chacun.
    Ce qui me dérange le plus, c'est que c'est typiquement le genre d'article qui va faire croire aux novices que la gestion de la mémoire est quelque chose d'ultra compliqué et risque au final de les éloigner du C++, alors qu'en réalité il s'agit d'un problème qui est loin d'etre insurmontable.
    "Toujours en faire plus pour en faire moins"

  5. #5
    Membre averti

    Profil pro
    Inscrit en
    décembre 2013
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2013
    Messages : 323
    Points : 429
    Points
    429
    Par défaut
    Pour les débutants, je ne suis pas sur. A un débutant, on lui montre les bonnes pratiques (il n'est pas nécessaire de s'attarder sur les mauvaises, il les apprendra très bien tout seul).
    Pour ceux qui écrivent ce genre de code, mais ne savent pas que cela risque de provoquer des fuites mémoire, je pense comme bountykiler qu'il aurait fallut présenter aussi le code correct en C++ "moderne" (pas forcement C++11, puisque beaucoup de problèmes signalés sont déjà réglés par le C++03 et surtout le RAII)

    Je ne critique pas le contenu de l'article en lui même. Apprendre à utiliser valgrind est toujours intéressant et il est utile pour les apprenants qui doivent faire la transition C++ "moderne" vers C++ old-school de savoir comment détecter les problèmes liés à ce genre de code.

    Mais j'ai du mal avec le titre, en particulier "C++11" et il manque des choses (les bonnes pratiques)

  6. #6
    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 : 42
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : juin 2002
    Messages : 2 165
    Points : 4 605
    Points
    4 605
    Par défaut
    Je rejoins mintho carmo : ça reste intéressant comme article de présentation de valgrind mais ce n'est pas un article sur "combattre les fuites et erreurs mémoires en C++".

    Au passage sur le chapitre IX "Facilités de C++11", outre ce qui a déjà été dit, il y a à la fois du C++03 (voire 98), C++11 et C++14 contrairement à ce que le titre suggère.

  7. #7
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2003
    Messages
    5 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : août 2003
    Messages : 5 273
    Points : 10 827
    Points
    10 827
    Par défaut
    valgrind, c'est mignon quand on n'a que ça (pour les objectifs de l'article) -- à condition de l'avoir aussi. Depuis, j'ai découvert les modes sanatize de clang et ... ça change la vie. Mieux que de savoir que l'on accède à une zone de mémoire qui ne nous appartient pas, il va aussi nous dire où la zone a été allouée ou aurait du être allouée (quand on est quelques octets après un buffer). Là, on est vraiment un niveau au dessus.

    Dernièrement, j'ai aussi eu à me battre avec des "Conditional jump or move depends on uninitialised value(s)". En termes d'origine de la valeur non initialisée je n'avais pas trouvé valgrind très bon sur des "int x = f(); if (x) ..." pour indiquer quel chemin dans f aura provoqué ces valeurs non initialisées. Je n'ai pas eu le temps de creuser le mode de sanatization (expérimental) équivalent malheureusement. Où alors c'était fait de façon statique, car il m'avait détecté plein d'idioties du genre "S::S(S const& rhs_) : m_i(m_i) {}" ou "S & S::operator=(S const& rhs_) { m_i = m_i; }" à la compilation.

    Pour la Programmation Défensive, oui cela en est effectivement. Et effectivement, je n'en pense pas du bien. Pour le 3e article, il est quasi prêt. J'ai juste un paragraphe à fignoler (et j'hésite à intégrer un mot sur les tous derniers papiers des derniers meetings au second article -- car sinon, je ne vais jamais m'en sortir).

    J'y pense, la classe Database n'est pas robuste à la duplication non plus.
    Après en effet, l'article aurait plus dû s'appeler "traquer les fuites de mémoire" que "combattre". Car on commence par combattre avec un egrep "new|alloc|fopen" (C++14); et un egrep "delete|free|close" qui ne doit renvoyer aucune occurrence hors destructeur (C++98). Les erreurs d'accès (mauvais index), c'est l'étape d'après. Sur le sujet on a aussi les assertions, et peut être un jour une analyse statique des contrats -- cela dépendra du résultat des discussions sur le sujet lors des divers meetings de préparation du C++17.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Avant d'agonir l'auteur de vos remarques, pensez que les débutants en informatique ne vont pas qu'écrire du code neuf selon des bonnes pratiques. Certains vont reprendre du vieux code écrit par des porcs et surveillés par eux. Des exemples de ce qu'ils pourraient être amené à trouver dans ces cas n'est pas inutile.

  9. #9
    Membre averti

    Profil pro
    Inscrit en
    décembre 2013
    Messages
    323
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2013
    Messages : 323
    Points : 429
    Points
    429
    Par défaut
    Citation Envoyé par fenkys Voir le message
    Avant d'agonir l'auteur de vos remarques
    On va se gener, il n'est pas la pour se defendre, c'est encore plus drole

    Citation Envoyé par fenkys Voir le message
    pensez que les débutants en informatique ne vont pas qu'écrire du code neuf selon des bonnes pratiques. Certains vont reprendre du vieux code écrit par des porcs et surveillés par eux. Des exemples de ce qu'ils pourraient être amené à trouver dans ces cas n'est pas inutile.
    Relis ce que l'on a écrit, personne ne lui reproche d'avoir écrit du code old-school (cela peut se comprendre dans certains cas, en particulier pédagogique ou pour apprendre valgrind). Ce qui nous embêtes (en tout cas moi - je ne vais pas parler a la place des autres), c'est qu'il fait le constat que ces codes posent problèmes, mais ne montre pas les solutions. C'est très dommage et c'est probablement pas ce qu'il faut faire pour corriger les mauvaises pratiques.

  10. #10
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2003
    Messages
    5 273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : août 2003
    Messages : 5 273
    Points : 10 827
    Points
    10 827
    Par défaut
    Disons qu'à sa décharge, corriger les fuites, c'est complexe si on veut les corrections minimalistes (i.e. qui restent dans le style du old-school pré-boost/ACE/loki). Bien qu'excessivement simple à prévenir (avec du 100% RAII ou équivalent (smart-pointers)) -- le coût le plus important, c'est d'enseigner le comment, les pourquois et les conséquences du RAII à des gens qui ont déjà des habitudes qui leur suffisent et qu'ils ne tiennent pas à changer.

    [Dans la formation que je donne au taf', je prenais l'exemple de la FAQ avec la base de données pour illustrer le RAII. Maintenant, j'ai rajouté les exemples du billet d'Aaron Lahman, traduit par Alexandre, pour illustrer pourquoi ils veulent vraiment employer le RAII, même s'ils ne le savaient pas encore. Dire que le code n'aura plus de fuite, c'est difficile à faire passer comme message. Là, je vais parier sur : "regardez, c'est beaucoup plus simple, cela ressemble au code naif qui fuit, et pourtant il n'y a pas de problèmes maintenant, ni plus tard quand on rajoutera encore d'autres chemins et opérations métier dans le code".]

    Corriger les accès hors-bornes, ce n'est pas trivial : cela va dépendre de chaque cas. De plus, il existe d'autres outils pour aider dans l'investigation : des STL en mode checked, ou encore le mode sanatize=address de clang (utilisé par gcc). Voire, des outils d'analyse statiques de code pourraient/pourront donner encore plus d'info en amont. Il propose un équivalent de at() (IIRC), à mon goût, c'est le pire des choix. Et ça, cela demande une discussion qui risque de faire exploser la longueur du billet si on veut être exhaustif.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. Fuite de mémoire dans les appels imbriqués ?
    Par Linschn dans le forum Langage
    Réponses: 14
    Dernier message: 07/10/2009, 14h19
  2. [débutant] comment éviter les fuites de mémoire ?
    Par dahtah dans le forum Général Java
    Réponses: 6
    Dernier message: 13/03/2007, 17h40
  3. Comme intercepter les fuites de mémoire sous VS?
    Par Gabrielly dans le forum Visual C++
    Réponses: 4
    Dernier message: 18/09/2006, 20h57
  4. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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