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
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.
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é ?)
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 :
Mais il est possible que j'extrapole un peuLorsque 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 ;
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.
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"
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)
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.
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...
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.
On va se gener, il n'est pas la pour se defendre, c'est encore plus drole
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.
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...
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager