Sur mon netbook avec 1Go de RAM, je déteste particulièrement les programmes qui bouffent de la mémoire dans le vide. Et quand un programme qui affiche la date, le niveau de batterie et deux trois autres informations mangent 4 fois plus que ce qu'utilise xmonad, je suppose un problème.
Je récupère le code source et je regarde. Du C qui est du C++ ou le contraire, mais bon, passons. Je n'ai pas prévu de faire la moindre correction au code. Je regarde juste … et je m'étrangle sur les deux lignes suivantes :
/* ... */
src_dup = (char*) realloc(src_dup, dup_len * sizeof(char));
sprintf(src_dup + dup_idx, "%s", templates[tmpl_num - 1]);
/* ... */
Si on lit la page de man de realloc :
void *realloc(void *ptr, size_t size);
[...]
The realloc() function returns a pointer to the newly allocated memory, which
is suitably aligned for any kind of variable and may be different from ptr,
or NULL if the request fails. If size was equal to 0, either NULL or a
pointer suitable to be passed to free() is returned. If realloc() fails the
original block is left untouched; it is not freed or moved.
Une utilisation correcte de realloc en C devrait ressembler à ça :
/* ... */
tmp=realloc(ptr, new_size);
if(tmp!=NULL) {
ptr=tmp;
/* ... */
}
Si la ré-allocation n'est pas possible, NULL
est retourné. Ensuite le pointeur retourné peut être différent de celui passé en paramètre, il est donc nécessaire d'assigner la valeur retournée au bon pointeur.
Vous me croyez pas ? La FAQ C ne laisse aucun doute.
Voilà, c'est tous ce que j'avais à dire.
Et puisqu'il semble qu'il ait une tradition qui fasse grincer des dents, voici quelque chose en rapport avec le journal.
PS: Il faudrait que je patch les 15 realloc de conky, mais comme je sais pas si c'est du C ou du C++, je sais pas si je vais le faire.
# Rapport avec la conso mémoire.
Posté par brendel . Évalué à 10. Dernière modification le 07 septembre 2012 à 16:45.
C'est mal de pas faire de test de pointeurs à NULL… Mais il est ou le rapport avec la conso mémoire?
Je veux dire, ce genre d'erreur est très commune, surtout dans ce genre de cas (logiciel non critique, et si la taille des donnée à allouer est très petite, peu de chance que ça foire), donc ne t'offusque pas chaque fois que tu en vois une ;)
[^] # Re: Rapport avec la conso mémoire.
Posté par Etienne Bagnoud (site web personnel) . Évalué à 8.
Comme c'est fait là, si la ré-allocation échoue, on a plus de pointeur vers la mémoire allouée avant la ré-allocation donc on ne peut plus libérer la mémoire donc on a une fuite mémoire.
C'est une erreur très commune, c'est pour ça que j'en fais un journal. Que le logiciel ne soit pas "critique" ou que les données soient "petites" ne constitue pas une excuse pour coder n'importe comment.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Rapport avec la conso mémoire.
Posté par liberforce (site web personnel) . Évalué à 10.
Comme dit en dessous, tu passes à côté du problème. Si realloc renvoie NULL, tu auras un SEGFAULT la ligne suivante, dès qu'on essaiera d'écrire avec sprintf. Du coup ta fuite mémoire vient forcément d'ailleurs.
[^] # Re: Rapport avec la conso mémoire.
Posté par mackwic . Évalué à -10.
Pas du tout, il a raison, mais son code correctif est incomplet.
Ça serait plutôt ça:
Si on ne compare a aucun moment
tmp
etptr
, le premier pointeur sera perdu dans la mémoire assez souvent. C'est ballo[^] # Re: Rapport avec la conso mémoire.
Posté par Zylabon . Évalué à 6.
Please do not feed the trolls
[^] # Re: Rapport avec la conso mémoire.
Posté par mackwic . Évalué à 1.
A ma décharge, ce n'était pas cité dans le journal et c'était bien plus logique pour expliquer une fuite de mémoire.
[^] # Re: Rapport avec la conso mémoire.
Posté par vincent LECOQ (site web personnel) . Évalué à 5.
plus généralement, le mal c'est la sombre flemme de vérifier les retours de fonctions ou appels systèmes !
# Et ?
Posté par flagos . Évalué à 3. Dernière modification le 07 septembre 2012 à 16:47.
Je vois pas trop où es ton souci.
Ok, il aurait du tester le != NULL. C'est pas la fin du monde non plus.
C'est pas ce qui est fait ?
[^] # Re: Et ?
Posté par Etienne Bagnoud (site web personnel) . Évalué à 0.
Oui c'est ce qui est fait et si c'est NULL, on a un bloc mémoire avec plus un seul pointeur pointant dessus pour le libérer. Et donc on a une fuite de mémoire ! Et si on utilise un ordinateur portable qui ne redémarre jamais (entrer/sortir de veille) et bien la fuite peut prendre des proportions énormes !
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Et ?
Posté par Buf (Mastodon) . Évalué à 10.
Si NULL est retourné, le programme va SEGFAULT à plus ou moins court terme. Du coup, la fuite mémoire, c'est plus vraiment un gros problème.
[^] # Re: Et ?
Posté par oinkoink_daotter . Évalué à 4. Dernière modification le 08 septembre 2012 à 00:07.
Pis bon, si les reallocs/mallocs et autres callocs comment à retourner NULL, clairement le test d'un retour d'appel système ne sera à très court terme plus le principal problème. OOMKiller dans la place \o/.
(hors limits et quotas, parce que c'est pas fun!)
[^] # Re: Et ?
Posté par groumly . Évalué à 5.
Ou pas.
Tu peux en profiter pour dropper un gros bout de memoire qui est utile mais pas vital.
Ou tout simplement, juste parce que tu va te bananer ne veut pas dire qu'il faut le faire a la rache.
Tu peux vouloir fermer un fichier proprement, logger que telle partie de l'appli a pas pu avoir sa memoire, (vainement) tenter de sauver qq chose, ou tout simplement prevenir l'utilisateur que "attention cherie, ca va trancher".
Envoyer ton appli au tas comme un cochon, c'est un peu violent quand meme.
Oui, c'est chiant et lourd, mais fallait pas choisir le C si la facilite de development etait un critere important :)
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Et ?
Posté par allcolor (site web personnel) . Évalué à 7.
Reste l'option de tuer le process, ça devrait libérer la mémoire… puis faire des trucs avec le pointeur NULL y a des chances qu'a un endroit ou l'autre ça segfault… ce qui libérera la ram… bon je ===>[]
[^] # Re: Et ?
Posté par flagos . Évalué à 1.
Bien vu effectivement.
# malloc() et realloc() sous linux
Posté par Damien Thébault . Évalué à 10.
À vrai dire, sous linux par défaut, malloc() et realloc() ne retournent finalement jamais NULL. Ce qu'il se passe plutôt, c'est qu'on reçoit toujours un pointeur, et c'est au moment où on se met à l'utiliser qu'il alloue réellement la mémoire.
Si au moment où on utilise la mémoire, celle-ci n'est pas disponible parce que la mémoire est pleine, alors le OOM-killer rentre en jeu et va tuer un process (que ça soit le process lui-même ou un autre).
Cette technique de lazy allocation permet notamment d'allouer plus de mémoire que ce qui est disponible physiquement (tant que toute cette mémoire allouée n'est pas utilisée). Ce comportement peut être modifié par des paramètres overcommit dans /sys/.
Cependant, même avec l'overcommit totalement désactivé, le noyau linux continuera à renvoyer un pointeur non-NULL, même quand il n'y a plus de mémoire disponible, et OOM-killer sera appelé comme d'habitude quand la mémoire sera accédée.
Au final sous linux il y a à priori une seule façon d'avoir ces fonctions qui retournent NULL, c'est en cas de fragmentation trop importante de l'espace d'adressage du processus qui rendrait impossible une allocation de la taille souhaitée, et c'est vraiment très très rare.
Voilà la raison pour laquelle vérifier le retour de malloc() et realloc() est en général assez peu utile, et pourquoi realloc() est assez souvent non testé pour NULL (les développeurs testent en général quand même avec malloc() car c'est plus facile à faire que avec realloc()).
Je préfère personellement quand même tester la valeur de retour quand même, ça permet d'être tranquille en cas de portage sur un autre unix, ça diminue les retours de logiciels d'analyse statique tel que clang et ça évite les questions en cas de revue de code.
[^] # Re: malloc() et realloc() sous linux
Posté par rahan . Évalué à 1.
Sauf en 32 bits. Où il est facile de se retrouver dans ce cas après avoir alloué puis libéré de grosses quantitées de mémoire (~1 GB ). D'où l'intérêt d'utiliser un noyau 64 bits dans ce genre de cas.
[^] # Re: malloc() et realloc() sous linux
Posté par ymorin . Évalué à 4.
Oui, mais pas seulement.
Ici, on est en
userland
, donc on parle de mémoire virtuelle. Sur 32-bit, cette espace est de 4GiB, dont 1GiB (*) est réservé pour l´espace d´adressage noyau (les pages de code (text
) du noyau est mappé dans l´espace virtuel de tous les processus, mais elles ne sont pas nécessairement exécutables : cela sert par exemple à appeler lessyscals
; les pages de data ne sont pas (toutes?) mappées dans l´espace d´adressage du noyau).Donc, il reste virtuellement (Haha!) 3GiB de disponible pour chaque processus en
userland
. Si ton processus essaye d´allouer en séquence des blocs de (par exemple) 1MiB sans les libérer, alors arrivera un moment ou même l´espace virtuel sera entièrement utilisé.Bien sûr, tu as aussi raison. Si tu alloues des blocs de 1MiB en séquence jusqu`à plus-soif, que tu en libères alternativement un sur deux, et qu´ensuite tu tentes d´allouer un bloc de 2MiB, alors tu as virtuellement de la place, mais pas contigüe, donc l´allocation vas échouer.
Donc, la règle générale deviendrai un truc du genre :
(*) la découpe noyau/
userland
est par défaut 1GiB/3GiB, mais 2GiB/2GiB ou 3GiB/1GiB est aussi possible.Hop,
Moi.
[^] # Re: malloc() et realloc() sous linux
Posté par Antoine . Évalué à 10.
Sous Linux peut-être, mais pas quand on écrit du C portable.
[^] # Re: malloc() et realloc() sous linux
Posté par neologix . Évalué à 10.
Ok, c'est l'overcommit.
C'est faux :
Test :
Normal, je suis sur 32-bit, plus d'espace d'adressage.
Maintenant, et activant l'overcommit strict :
En faisant un memset() sur le block retourné par malloc(), dans le premier cas le process se fait tuer par l'OOM killer, dans le deuxième le comportement est le même.
[^] # Re: malloc() et realloc() sous linux
Posté par Damien Thébault . Évalué à 3.
Bien vu ! Au temps pour moi, on peut donc bien recevoir NULL même sous GNU/Linux grâce à l'overcommit.
# Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 9.
Ne le fait pas.
Dans un programme utilisateur ça n'a aucun intérêt.
Le mieux que tu puisse faire c'est un truc du style
C
assert(src_dup);
Si tu veux éviter les éventuelles faille de sécurités. Mais pour un 'bête' programme utilisateur du style concky, il n'y a pas grands risque. Tout ce que tu fais c'est perdre des cycles à tester et rajoute du code qui prends de la place en cache.
Gérer les "OOM" (Out Of Memory) est inutile pour deux raison:
1 - C'est impossible de tester tout les cas possible d'échec de realloc. Et du code non testé à de forte chance de ne pas fonctionner
2 - Les systèmes d'exploitation moderne "overcommit" la mémoire. Ça veux dire que même si il n'y a plus de mémoire, réalloc va quand même fonctionner. Et c'est au moment ou cette mémoire va être utilisée que le noyaux va devoir récupérer de la mémoire en tuant un processus (OOM killer) (en utilisant des heuristique, mais pas forcément celui qui demande la mémoire).
Bien sûr il y a des cas ou c'est nécessaire de gérer ça correctement (en embarqué par exemple). Mais pas ici.
[^] # Re: Ne le fait pas.
Posté par un_brice (site web personnel) . Évalué à 6.
Pour être plus précis: les cas en questions sont assez nombreux et dépendent du contexte d'éxécution. Quand tu programme tu ne sais souvent pas où ton code va finir après avoir été
copié/collérefactoré vingt fois.Pour donner un autre exemple sur un serveur ou dans une bibliothèque c'est vraiment pas ce qu'il y a de mieux à faire. Il faut tester et respectivement renvoyer une erreur au client (par ex indiquant de réessayer après un temps d'attente exponentiel en fonction du nombre d'erreurs) ou renvoyer à l'appelant un truc qui lui permet de faire ce qui convient.
Et accessoirement te conformer à l'API.
C'est pourtant facile d'injecter ce genre d'erreur.
Ça dépends entre autres de l'humeur de ton sysadmin, et dans tout les cas c'est pas dans l'API.
[^] # Re: Ne le fait pas.
Posté par Zenitram (site web personnel) . Évalué à -1.
Quand tu as ce genre d'erreur pour des petites demande de création mémoire comme un bête outil de l'exemple, que l'outil soit conforme ou pas à l'API est le dernier de tes soucis… à la limite si tu demandais un realloc(100*1000*1000), je comprendrai que tu rales que ce ne soit pas pris en compte, mais la : le programmeur a juste autre chose à foutre que de blinder de test un programme dans le but d'arriver à un niveau de logiciel de pilotage d'avion, alors que c'est juste un petit programme. Après, si tu sponsorises ce genre de développement, il sera sans doute content de le faire pour toi. En attendant : tout le monde (à part les gens qui n'ont rien à voir dans l'histoire : ni utilisateur ayant un crash ou une perte mémoire car il a été démontré que ce n'est pas possible, ni le dév') s'en fout!
[^] # Re: Ne le fait pas.
Posté par Sufflope (site web personnel) . Évalué à -4.
Je m'étonne de ne pas l'avoir déjà vu donc je me/le lance : le vrai problème c'est qu'il y a encore des gens pour utiliser un langage aussi archaïque et dangereux que le C (surtout pour un programme de très haut niveau qui sert à afficher des graphiques pouet pouet ; pour de l'embarqué ou pour un noyau c'est autre chose).
[^] # Re: Ne le fait pas.
Posté par Marotte ⛧ . Évalué à 4.
Vieux troll velu qui ne passera pas.
On peut faire dans le très dangereux en C++, Java, Python, Perl comme en C. On peut aussi faire du C de manière très safe. Le C est peut-être archaïque mais c'est le langage le plus généraliste et éprouvé qui soit.
[^] # Re: Ne le fait pas.
Posté par Zylabon . Évalué à 2.
Puis quand on cherche à faire light, c'est l'idéal, on peut contrôler on ne peux plus finement la taille du tas.
Please do not feed the trolls
[^] # Re: Ne le fait pas.
Posté par Michaël (site web personnel) . Évalué à 2.
C'est seulement vrai si tu connais bien ton allocateur de mémoire.
De plus, en C tes données ne peuvent être déplacées après avoir été allouées, donc un programme C est particulièrement vulnérable à la fragmentation de la mémoire.
[^] # Re: Ne le fait pas.
Posté par Marotte ⛧ . Évalué à 1.
J'espère ne pas dire trop de bêtise mais il me semble quand même qu'en faisant de la copie (on alloue un nouvel espace mémoire puis on y copie le contenu des autres espaces mémoire) on peut défragmenter cette mémoire. Sur que c'est du boulot pour le programmeur mais un programme en C n'est pas particulièrement (plus que ça) vulnérable à la fragmentation mémoire.
[^] # Re: Ne le fait pas.
Posté par Michaël (site web personnel) . Évalué à 2.
Indice: pointeur.
[^] # Re: Ne le fait pas.
Posté par Batchyx . Évalué à 3.
C'est le bon vieux problème de l'invalidation des pointeurs ou des itérateurs: Si tu à plusieurs pointeurs/itérateurs qui sont éparpillés partout qui pointent vers des éléments de ton espace mémoire, alors si tu déplace ton espace mémoire, ces anciens pointeurs/itérateurs deviennent invalides et il faut soit les mettre à jour soit arrêter de les utiliser.
C'est un problème qui arrive quelque soit le langage. La seule solution, c'est soit de laisser le programmeur bien choisir ses structures de données pour qu'il sache qui pointe vers quoi, soit que le langage l'impose à sa place…
[^] # Re: Ne le fait pas.
Posté par windu.2b . Évalué à 1.
Pour "résoudre" ce problème, ne serait-il pas envisageable de faire une table de traduction pointeurs <-> adresse-mémoire ? En cas de déplacement, seul l'adresse-mémoire change, mais pas le pointeur, ça reste donc transparent pour le programme.
Ceci aurait par contre un coût, puisqu'il faudrait alors passer par cette table, pour savoir où lire/écrire dans la mémoire, donc un ralentissement (mais de quel ordre ?)
Le jeu en vaut-il la chandelle ? Ne m'y connaissant pas du tout dans ce domaine, c'est juste là une réflexion rapide que je viens d'avoir avec moi-même…
[^] # Re: Ne le fait pas.
Posté par fearan . Évalué à 3.
Si c'est tout à fait envisageable, la question de si c'est utile va dépendre de l'application, mais si tu as besoin de passer par là j'aurais tendance a dire que d'autre pistes sont envisageable, comme allouer les structure de données en statique, avec une façon de retrouver lesquelles sont vides (via un flag ou une pile), ou allouer un gros chunck de mémoire et utiliser tes propres allocateurs adapté à ton besoin; globalement tu auras plus a gagné en faisant un truc adapté qu'une défragmentation manuelle qui peut, selon l'état de la mémoire ne pas changer grand chose, voire planter, tout en utilisant un bon paquet de ressources.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 10.
Euh non desole, c'est une question d'hygiene de base de mon point de vue.
Le dev qui laisse aller des trucs aussi basique, c'est vraiment qu'il se fiche de son code, qu'il ne pense pas loin et qu'il a certainement plein d'autres problemes dans son code.
Ton bete outil, il va un jour etre utilise a travers Apache par exemple, avec parametres passes par l'utilisateur parce qu'apres tout, ton outil est juste genre un convertisseur ou autre.
Et le jour ou ton malloc il va rater et tout le monde s'en fiche, ben tu te retrouves avec une faille de securite potentiellement exploitable selon les operations faites apres le malloc.
[^] # Re: Ne le fait pas.
Posté par Michaël (site web personnel) . Évalué à 9.
Quelles que soient ses motivations, un programmeur codant comme un cochon reste un programmeur codant comme un cochon. Et les cochons écrivent des programmes difficiles à debugger, difficiles à modifier, … autrement dit ils renoncent à l'aspect soft du software. Même si c'est un choix qui peut être parfois viable, il ne doit jamais être présenté comme anodin!
[^] # Re: Ne le fait pas.
Posté par lasher . Évalué à 6.
Bon je ne comprends pas vraiment là. Chez tout plein de gens, il est naturel de fournir des versions
static inline
un peu de cette façon-là:Bref, de proposer des versions « configurables » (car par ex là, ça va forcément toujours planter alors que parfois il existe des moyens de moyenner). Est-ce que ce ne serait tout simplement pas plus simple de toujours faire ainsi ? Comme ça au moins, on sait que quelqu'un, quelque part prend en charge ce genre de trucs, et le code du « vrai » programme n'a pas besoin d'être encombré de vérifications en tous genres…
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 3.
Pas si simple. Il faut aussi s'assurer que tout ce passe comme prévu : de ne pas garder de mutex ver ouillé par erreur, de bien libérer toutes les ressources qui ont été allouée par la fonction. De garder l'état du programme dans un état correcte, sans structure de donnée à moitié initialisées.
En plus l'utilisateur de la bibliothèque devra faire pareil et ajouter du code pour gérer cette erreur.
Et tout ça pour pas grand chose au final. Le plus simple est de terminer le programme immédiatement. Et de bien récupérer en cas de crash.
Les programmes qui ont vraiment besoin de gérer les cas d'OOM sont plutôt rares. Et il vaux mieux ne pas gaspiller de temps et de ressources à le faire.
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 10.
Non franchement non, pas d'accord.
Le BABA du programmer correct est la gestion d'erreur. Une allocation de ressource qui flanche ca arrive, et ca doit etre gere. Ton utilisateur quand il voit ton soft lui exploser dans les doigts, c'est vraiment pas ce qu'il attend et il ne comprendra meme pas pourquoi, sans parler du fait qu'il y a risque de faille de securite (selon les operations faites apres l'alloc) si tu ne le geres pas.
[^] # Re: Ne le fait pas.
Posté par gnumdk (site web personnel) . Évalué à -1.
La question que je me pose, c'est comment gérer correctement ce genre d'erreur quand ton programme fait une tache critique, tu va forcément faire de la merde, non ?
Ensuite, une autre question,
pour new, j'ai lu ici et ailleurs que ca lançait une execption.
J'ai lu sur d'autre site que ca renvoyait NULL.
N'ayant jamais vu de code C++ tester le cas, j'imagine que ca quitte "proprement" via une exception, non ?
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 4.
Ben t'as un chemin d'erreur normalement, si ton allocation rate, tu defais ce que tu avais fais et tu retournes une erreur.
Il y a forcement de tres rares cas ou il faut fermer l'application/tuer le systeme, mais dans ces cas-la, faut le faire le plus proprement possible (tu fermes les fichiers que tu ecris, tu logges un msg d'erreur, tu informes l'utilisateur, etc…)
Pour C++ normalement tu peux faire ton new avec std::nothrow qui forcera l'allocateur sans exception (tu recevras un NULL a la place), mais le defaut est de lancer une exception.
Quand a l'exception, ca va quitter le programme oui, mais c'est de nouveau pas forcement le bon resultat a avoir…
[^] # Re: Ne le fait pas.
Posté par Michaël (site web personnel) . Évalué à 3.
Eh oui, programmer n'est pas facile!
Et en plus il va écrire un programme tout autour! Quelle idée!
En réalité tous les programmes sont susceptibles de rencontrer un OOM, à cause du voisin qui a bouffé toute la place. Si tes programmes sont instables en cas d'OOM cela signifie que si un programme ange toute la mémoire les autres partent en cacahuète. Super.
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 3.
Ptet qu'on pourrait lister les programmes qui gerent correctement et gracieusement les situations OOM alors. Puisque tout le monde ici à l'air super au point sur comment faire ça plus elegamment qu'avec un assert, j'imagine que ces programmes sont très nombreux.
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 4.
En tous cas, aucun programme utilisant GLib ou GTK+ http://jeffreystedfast.blogspot.be/2008/02/worse-is-better-in-form-of-autosave.html
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 0.
Ils sont tres nombreux oui, a peu pres tous les softs serveurs, et chez nous tous les autres softs aussi(du moins tout ce qui est dans Windows et Office). Si on voit ca en code review c'est immediatement marque comme "a corriger" (et evidemment on en rate quelque uns qui atterissent dans le produit, on est pas parfait)
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 4.
Pour tout dire j'aurais preferé qu'on me cite des applications open-source, dont on peut voir le code et constater comme c'est beau et robuste à l'intérieur.
On peut par exemple consulter l'avis de l'ineffable Lennart Poetterring, (qui cite D-BUS comme exemple de demon robuste aux echecs de mallocs):
http://developer.pardus.org.tr/people/ozan/blog/?p=14
Je le cite: The OOM situation has been discussed quite often in various
projects. On modern systems it has become pretty clear that for normal
userspace software only an aborting malloc() makes sense for a couple
of reasons: (…)
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 9.
Et sa conclusion:
[^] # Re: Ne le fait pas.
Posté par YBoy360 (site web personnel) . Évalué à 1.
c'est exactement ce que je pensais, vouloir tester toutes les allocations, ça n'est pas gratuit en place mémoire, et ça rend le code moins lisible. De plus il vaut mieux un crash net, qui libère des ressources pour que le reste puisse fonctionner.
Je crois que je n'ai jamais vu ce cas de figure (malloc qui retourne null), j'aime pas le code mort.
[^] # Re: Ne le fait pas.
Posté par Zylabon . Évalué à 5.
Le poids de cette gestion d'erreurs peut être minime en traitant l'erreur une fois pour toute dans une fonction
Please do not feed the trolls
[^] # Re: Ne le fait pas.
Posté par YBoy360 (site web personnel) . Évalué à -4.
ou dans le gestionnaire de signaux, ça serait pas le bon endroit?
[^] # Re: Ne le fait pas.
Posté par Alex . Évalué à 4.
en interceptant SEGFAULT ?
le problème du segfault est que tu n'en connais pas son origine exacte, tu ne sais pas si tes données sont dans un état cohérent
et pour SIGKILL, de mémoire il ne peut être intercepté
[^] # Re: Ne le fait pas.
Posté par YBoy360 (site web personnel) . Évalué à -1. Dernière modification le 09 septembre 2012 à 13:07.
Oui, d'accord, seulement son code ne sert qu'a fermer ce que l'OS ne ferme pas lorsque le process est tué, il ne s'agit pas de faire des choses compliqués genre afficher un message d'erreur ou faire une sauvegarde, il ne maintient aucune variable d'état. C'est exactement ce que je dis de faire (pas traiter l'erreur au cas par cas).
Le problème avec son approche, c'est qu'en fonction des options de compilation et de l'architecture tu ne pourras pas avoir d'info sur l'endroit ou l'erreur à eu lieu. tandis qu'avec un bon vieux SIGSEGV j'ai une info sur l'endroit exacte (c'est discutable du point de vu de l'utilisateur).
[^] # Re: Ne le fait pas.
Posté par Alex . Évalué à 2.
tu as raison, si tu te contentes de crasher proprement comme en effet il indique
moi j'utilisais cette méthode pour sauver ce qui était sauvable. Ce n'est pas aussi complexe que du "cas pas cas", ce qui implique d'autres contraintes (données en accès, fd ouvert, allocation en début d'opérations et non en cour, etc…).
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 0.
Tu attaches un debugger, tu mets un breakpoint sur msvcrt!malloc, quand le breakpoint est touche, tu regardes l'assembleur juste apres l'appel, et tu verras une comparaison sur le registre eax, qui est le registre contenant la valeur de retour…
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 5.
Juste pour voir j'ai lancé wordpad avec "MS Application Verifier" qui tourne et dans lequel seul "Low Resource Simulation" est coché. Il m'a affiché 3 fois "La mémoire de votre ordinateur est insuffisante" (bien) puis il a planté (moins bien)
[^] # Re: Ne le fait pas.
Posté par Antoine . Évalué à 3.
Nombreux je ne sais pas, mais un langage haut niveau (implémenté en C, donc ce n'est pas hors sujet) peut lever une exception :
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 3. Dernière modification le 08 septembre 2012 à 15:45.
test fait sur un petit netbook avec peu de mémoire sous ubuntu:
Donc ça ne protege pas contre toutes les situations où la mémoire vient à manquer et où le systéme se lance dans une partie de ball-trap sur les process suspects
[^] # Re: Ne le fait pas.
Posté par Antoine . Évalué à 2.
Tout à fait, le problème ici étant probablement l'overcommit (le programme ne peut rien faire pour détecter le problème). N'empêche que ça marche tout de même dans pas mal de cas.
[^] # Re: Ne le fait pas.
Posté par 2PetitsVerres . Évalué à 4.
Et comment fais-tu pour protéger ton code qui sera copié/collé et modifié en introduisant un bug ? C'est à moi d'imaginer ce que des gens pourraient faire de mon code en le modifiant ? Chacun sa merde.
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 2.
Le mieux que tu puisse faire c'est un truc du style
C
assert(src_dup);
Euh non, parce que si tu fais ca, en cas d'echec d'allocation, ton programme il meurt. Tuer un soft parce qu'une allocation a echoue c'est franchement crade, tu avortes la requete ou l'operation, tu logges une erreur si besoin est, mais tu continues de tourner.
[^] # Re: Ne le fait pas.
Posté par Zylabon . Évalué à 5. Dernière modification le 08 septembre 2012 à 00:14.
Puis à priori on compile avec NDEBUG pour utiliser un soft (surtout si on veut qu'il soit léger), donc l'assert saute. L'assert est plus adapté pour contrôler la validité d'arguments passé à une fonctions qu'a gérer ce genre d'erreurs.
Please do not feed the trolls
[^] # Re: Ne le fait pas.
Posté par Lizzie Crowdagger (site web personnel) . Évalué à 3.
En même temps ça dépend beaucoup du type de programme et d'alloc, non ? Dans certains cas, arrêter le programme s'il peut pas avoir sa mémoire paraît assez logique et loin d'être dramatique ; c'est sûr que si c'est gimp qui crashe avec toutes tes images ouvertes parce que t'as essayé de crééer une image 100000*100000, c'est plus emmerdant.
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 3.
Arreter le programme peut-etre oui, selon ce que le soft fait, mais il faut le faire proprement , pas avec un SEGFAULT ou un assert.
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 0.
Peut être pour un serveur ou une application critique. Mais pour un programme avec une interface graphique, ça n'en vaux pas la peine.
Ça demande énormément de travail pour aucun gain.
[^] # Re: Ne le fait pas.
Posté par vincent LECOQ (site web personnel) . Évalué à 5.
c'est sur, le jour ou en manque de RAM ton firefox va quitter completement sur un simple Ctrl-T …. au lieu de te dire, non, pas un nouvel onglet merci. tu sera heureux ?
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 1.
Désolé, mais c'est pas déjà le cas ?
Qu'est-ce qui se passe d'après toi, quand il n'y a plus de mémoire avec firefox ?
[^] # Re: Ne le fait pas.
Posté par 2PetitsVerres . Évalué à 2.
Heureux, je ne sais pas, mais de toute façon il n'y a rien de critique qui tourne dans un navigateur. Et sinon s'il n'y a plus de mémoire, si firefox gère ça "correctement" dans ton idée (c'est à dire ne pas ouvrir ton onglet) tu seras content de savoir qu'il peut se faire OOMkiller d'ici quelque instants, parce qu'une autre application aura besoin de mémoire.
Tous les nombres premiers sont impairs, sauf un. Tous les nombres premiers sont impairs, sauf deux.
[^] # Re: Ne le fait pas.
Posté par Troy McClure (site web personnel) . Évalué à 2.
hum je sais pas si tu as déjà vu firefox mourir dans une situation où la mémoire manque, mais moi je l'ai vu à moultes reprises sur un laptop tout moisi et il se fait juste flinguer par le OOM-killer sans sommations
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 0.
De nouveau, rien a voir.
malloc te retourne null si l'espace memoire de Firefox est fragmente et si il tente un gros alloc, meme si il reste plein de RAM. OOM-killer ne levera pas un doigt dans ce cas.
[^] # Re: Ne le fait pas.
Posté par vincent LECOQ (site web personnel) . Évalué à 1.
je prenais le cas du navigateur et les onglets comme exemple, j'ai pas lu le code de ff pour vérifier si j'ai fait le bon choix en le citant …
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 0.
Tu penses ?
Tu es en train de mettre la derniere touche a ton livre de 400 pages, et tu as Firefox en arriere plan qui bouffe toute la RAM, alors que OpenOffice essaie de sauver, il se retrouve avec un malloc qui rate, tu penses qu'il devrait exploser en vol et corrompre le document ou s'en sortir proprement ?
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à -1.
Et si il y a une coupure de courent, ou que te femme débranche la mauvaise prise pour brancher l'aspirateur alors que tu met la dernière touche ?
Comme on est jamais à l'abri des bugs, il faut toujours gérer les crash proprement. Autosave, et modification atomiques des fichier (enregistrer une copie, et atomiquement remplacer l'original).
Et donc tu ne perds pas plus de quelque minutes de travail.
[^] # Re: Ne le fait pas.
Posté par pasBill pasGates . Évalué à 3.
Alors vu qu'il y a une possibilite qui existe que ca merde et corrompe le fichier (prise de courant), autant ne jamais gerer les problemes d'allocation et laisser le fichier etre corrompu dans tous les cas ?
On va aller loin avec une approche pareille, et tu en fais quoi du fait que l'utilisateur n'a aucun moyen de comprendre ce qui s'est passe ?
Qu'il doit se retaper ce qu'il a perdu avec les softs qui n'ont pas d'auto-save ? (et le soft pourrait planter au milieu de l'auto-save hein…)
Que cette approche a la porc ouvre la porte a plein de failles de securite ?
Que cette approche peut corrompre la configuration du soft et l'empecher de redemarrer plus tard ?
etc…
[^] # Re: Ne le fait pas.
Posté par Zylabon . Évalué à 1.
Ça me rappelle ce que disent les dev d'erlang. Grosso modo "les bugs sont des problèmes comme les autres qui peuvent être traités comme les autres".
Please do not feed the trolls
[^] # Re: Ne le fait pas.
Posté par Gof (site web personnel) . Évalué à 4.
Tu m'a mal compris.
Je voulais dire que vu qu'il est toujours possible que ça crash, il faut faire en sorte que les conséquences soient minimes en cas de crash. Merci autosave.
Et que vu que ce n'est pas si grave si ça crash, alors autant laisser crasher dans le cas de OOM.
En effet, gérer proprement toutes les situation de OOM est un travail énorme.
Je préfère des soft qui ont l'auto-save et pas de gestion d'OOM que l'inverse
C'est pourquoi l'enregistrement doit se faire de façon atomique, pour que la sauvegarde précédente soit toujours là.
Pareil pour la configuration.
[^] # Re: Ne le fait pas.
Posté par vincent LECOQ (site web personnel) . Évalué à 2.
a vrai dire, a part quelques précautions comme un save régulier, un soft a peu d'armes contre une coupure de courant …
[^] # Re: Ne le fait pas.
Posté par groumly . Évalué à -1.
Effectivement.
Et si un meteorite s'ecrase sur la machine, alors le disque dur est foutu, et donc c'est pas la peine de s'emmerder a gerer correctement des erreurs softs.
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Ne le fait pas.
Posté par Zenitram (site web personnel) . Évalué à 3.
Faut pas déconner : C'est réel, la vraie vie, que le courant te lâche plus souvent qu'un malloc à NULL.
La priorité est clairement la gestion des coupures de courant (ou simplement un crash de l'OS, même Linux).
[^] # Re: Ne le fait pas.
Posté par groumly . Évalué à 2.
Dans le monde mobile, tu vas t'approcher des limites de memoires plus souvent que des pb de batteries.
D'ou des designs adaptes, certes.
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Ne le fait pas.
Posté par Zenitram (site web personnel) . Évalué à -1.
Mais que vient faire la limite de mémoire ici???
ON NE PARLE PAS DE FUITE MEMOIRE.
On parle de crash (dans l'exemple donné, il n'y a pas de fuite mémoire, si realloc retourne NULL, ça a déjà été dit que ça crashe)
Je me répète donc : Oui, il ne faut pas laisser les fuites mémoires pour un programme permanent (pour un programme qui s’exécute 5 minute, rien à foutre. Encore une fois, la chasse à ces problème dépend du contexte, ça ne DOIT PAS être une règle fixe). Chasser le realloc à NULL, ton OS a DEJA un gros problème, rien à foutre qu'il crashe ce petit logiciel.
[^] # Re: Ne le fait pas.
Posté par Antoine . Évalué à 2.
Ben si. Si realloc ou malloc échoue, il y a de fortes chances que ce soit dû à une fuite mémoire qui a épuisé la mémoire disponible.
(l'autre cas courant étant l'erreur de programmation)
[^] # Re: Ne le fait pas.
Posté par groumly . Évalué à -1.
Je parle pas de fuite, je parle de pas planter ton soft comme un boeuf parce que t'as la flemme de verifier tes codes de retour.
L'utilisateur en sait rien qu'il n'y a plus de memoire, la moindre des choses ca serait se lui dire.
Ensuite, sur un soft client, avec UI et tout le tralala, je suis a peunpres sur que tu as un paquet de memoire que tu peux liberer (toutes les vues non affichees). Droppes ca, tu recuperes un gros paquet de memoire. Et c'est marrrant, c'est le modele d'ios, l'os va te demander de liberer des ressources quand tu t'approches de la limite.
Sur un soft serveur, t'as tres probablement un cache en memoire qq part que tu peux vider histoire de liberer des ressources.
Et clairement, la moindre des choses a faire c'est de logger une ligne pour mettre les admins au courant que ca a plante a cause de ca.
Apres, t'es libre de considerer que c'est ok de se mettre au tas comme ca, et d'avoir pour seule reaction de hausser les epaules en disant "a foutre, ca prend du temps", ca veut pas dire que c'est acceptable comme attitude.
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Ne le fait pas.
Posté par groumly . Évalué à 1.
J'oubliais le plus important: ton soft ne peut rien faire contre une panne de courant. Il peut faire qq chose s'il se retrouve short en memoire.
Linuxfr, le portail francais du logiciel libre et du neo nazisme.
[^] # Re: Ne le fait pas.
Posté par Antoine . Évalué à 3.
Dans ma vraie vie à moi, j'ai plus souvent vu des échecs d'allocation mémoire que des coupures de courant.
(et pourtant je te parle de mon chez moi domestique sans onduleur ; pour un serveur dans un datacenter c'est probablement encore plus flagrant)
[^] # Re: Ne le fait pas.
Posté par ondex2 . Évalué à 6.
Ca dépend. Pour ceux qui sont à TH2, les coupures de courant régulières permettent de libérer la mémoire avant qu'une fuite de mémoire ne vautre le serveur…
# realloc() et fragmentation du tas
Posté par neologix . Évalué à 5.
Comme expliqué ci-dessus, dans ce cas il n'y aura pas de fuite mémoire, en cas d'OOM ça finit soit avec le OOM killer soit en segfault.
Mais realloc() a une particularité intéressante qui rend facile l'introduction d'une fragmentation du tas : lorsqu'on appelle un realloc() avec une nouvelle taille inférieure à la taille d'origine, certaines implémentations [1] ne réduisent pas le bloc d'origine. C'est-à-dire qu'une séquence du style :
Conduit à une grosse fragmentation du tas. On a eu ce genre de problème dans cPython.
[1] La glibc n'est pas affectée (http://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=ca1d73f875150a17955df9e0aa2dc33e277aacb5;hb=HEAD#l4168), mais la libc de OS-X si par exemple.
# Paie ton code d'amateur quand même ...
Posté par galactikboulay . Évalué à 2.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Lizzie Crowdagger (site web personnel) . Évalué à 4.
Certes, et en même temps c'est pas gênant de l'écrire (a priori le compilo va optimiser) et je trouve que c'est pas forcément un mal de le mettre personnellement (je trouve que ça permet de voir directement qu'il n'y a pas eu d'oubli de multiplier par la taille du type). Enfin je dis pas que c'est le truc à faire, mais moi je trouve ça plus cohérent d'avoir un "x * sizeof (char)" au milieu de "y * sizeof (int)" et "z * sizeof (double)", même si c'est inutile.
Il me semble qu'en C++ tu te chopes une erreur ou un warning si tu le fais pas.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par vincent LECOQ (site web personnel) . Évalué à 3.
en effet le style indique un utilisateur de g++ plutôt que gcc
par contre pour le sizeof je préfère franchement un sizeof(*ptr) plutôt qu'un sizeof(type) …
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Obsidian . Évalué à 4.
Tiens, puis accessoirement, puisqu'on en parle et contrairement à une idée répandue, « sizeof » n'utilise pas de parenthèses. On les met quand on veut connaître la taille d'un type mais, dans ce cas, c'est au nom de ce type qu'elles s'appliquent (comme un cast). C'est une erreur compréhensible parce que d'une part, les mettre forme toujours une expression syntaxiquement correcte et (surtout) « sizeof » est le seul mot-clé réservé du C qui se comporte comme une fonction.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par vincent LECOQ (site web personnel) . Évalué à 1.
J'ai toujours prefféré mettre plus de parentheses que de raison, j'aime pas me laisser de doute.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Batchyx . Évalué à 4.
Si tu utilise malloc en C++, c'est normal de te faire battre, puisque tu à tendu le bâton.
Pour information, en C++, new te force à spécifier le type, et ne retourne jamais NULL (ça lance une exception à la place).
Et sinon, conky est compilé avec un compilo C … donc aucune raison de caster le malloc.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Lizzie Crowdagger (site web personnel) . Évalué à 2.
«Si tu utilise malloc en C++, c'est normal de te faire battre, puisque tu à tendu le bâton.»
Mais euh, c'est pas moi d'abord !
«Et sinon, conky est compilé avec un compilo C … donc aucune raison de caster le malloc.»
Au temps pour moi, comme le journal disait «Du C qui est du C++ ou le contraire» je pensais que c'était de la syntaxe style C compilée avec un compilo C++…
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Etienne Bagnoud (site web personnel) . Évalué à 2.
Il y'a des bouts de vrai C++ (template C++), donc il doit être compiler avec un compilateur C++.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Batchyx . Évalué à 2. Dernière modification le 09 septembre 2012 à 16:00.
Ah ? ou ça ? Parce chez moi :
Donc j'aimerai bien savoir comment il pourrai y avoir des templates dans ce code… à croire qu'on ne parle pas du même logiciel.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par LeMagicien Garcimore . Évalué à 2.
http://git.omp.am/?p=conky.git;a=blob;f=src/llua.cc;h=3b56e0363ae223883db204aa7e042adce84dcf9f;hb=refs/heads/master
et j'ai vu quelques #include <algorithm> …
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Batchyx . Évalué à 3.
Ok, il n'y avais juste rien de tout ça dans la version stable …
Mais bon je maintiens ce que je dit : utiliser malloc() nu en C++, c'est tendre le baton pour se faire battre.
[^] # Re: Paie ton code d'amateur quand même ...
Posté par lasher . Évalué à 4.
J'ai pertinenté, mais juste pour abuser un peu des mouches : il existe UN cas parfaitement justifié pour utiliser malloc/realloc/free : lorsque tu surcharges
operator new
… :)[^] # Re: Paie ton code d'amateur quand même ...
Posté par Michaël (site web personnel) . Évalué à 5.
En C, caster les mallocs sert seulement à ne pas voir qu'on a oublié le header stdlib.h. Du coup ton compilateur génère un prototype de fonction dont le type de retour est
int
. Si tes entiers et tes pointeurs n'ont pas la même taille, c'est l'hosto direct![^] # Re: Paie ton code d'amateur quand même ...
Posté par gaaaaaAab . Évalué à 2.
le seul point valide de ton commentaire porte sur le test des codes de retour. Le reste, c'est de la pure convention pour lesquels les deux comportements sont admissibles (sizezof(char) ou pas, et caste de *alloc ou pas).
Sur un extrait de lignes, ça fait un peu court pour en déduire quoi que ce soit sur le professionnalisme de l'auteur du code, non ?
[^] # Re: Paie ton code d'amateur quand même ...
Posté par Michaël (site web personnel) . Évalué à 2.
On ne caste pas les malloc, cela ne sert à rien et peut cacher une faute (oubli de l'inclusion de stdlib.h) qui peut déclencer un UB si sizeof(int) != sizeof(void*).
# xmonad n'est pas si léger que ça.
Posté par Zylabon . Évalué à 2.
J'ai eu envie d'essayer récemment. Certes, il occupe très peu de RAM, mais le CPU !
Perso, de la RAM, j'en ai, mais je me soucie de l'autonomie de ma batterie, et xmonad réveille le CPU plus souvent que le wifi. C'est peut être un bug, j'utilisais l'overlay haskell de gentoo.
Please do not feed the trolls
[^] # Re: xmonad n'est pas si léger que ça.
Posté par Pierre Carrier . Évalué à 1.
Oui, c'est un bug connu.
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677096
# Où va la mémoire ?
Posté par Gof (site web personnel) . Évalué à 4.
Ce qu'il faut faire pour voir pourquoi ton programme prends autant de mémoire:
T'assurer que c'est bien le tas (heap) qui prends la mémoire, et pas un fichier mapper (par exemple, le code des bibliothèques, ou un fichier de polices)
valgrind --tool=massif, et regarder le résultat avec massif-visualizer
# Idem avec Conky
Posté par Anonyme . Évalué à 1. Dernière modification le 08 septembre 2012 à 00:17.
J'utilisais Conky, et j'avais le même problème de fuite mémoire. Comme l'ordinateur tourne 24/7, le processus de Conky arrivait rapidement à bouffer plus de 300~400M de mémoire, point auquel il devenait gênant et qui valait donc que je le dégage.
Ne m'y connaissant pas des masses, j'ai rapidement cherché des informations sur le net à ce sujet, et visiblement plusieurs personnes s'en plaignaient sur différents forums. Ne sachant toujours pas si la fuite venait de Conky ou de mon fichier conkyrc (qui affichait une belle horloge à aiguilles, un calendrier et les jauges d'utilisation mémoire, disque et processeur), j'ai dégagé le logiciel pour ne plus être ennuyé.
# Chaque amélioration compte
Posté par philou . Évalué à 6.
J'ai pu lire une ou deux fois que ce n'était pas une correction très importante ou qu'elle n'était peut-être pas responsable de la fuite mémoire. Sans toucher à ce débat, j'aimerais ajouter quelque chose. Et alors ? C'est une raison pour ne pas améliorer l'application ?
L'immobilisme mène à la dégradation du code, la dégradation mène à la non maintenabilité, la non maintenabilité mène à la colère, la colère au côté obscur. Dark Vador, c'est un peu de votre faute finalement.
[^] # Re: Chaque amélioration compte
Posté par Zenitram (site web personnel) . Évalué à 1.
Dans l'exemple cité, il n'y a pas de fuite mémoire (ça crashe).
Ce n'est pas le problème.
Je suis d'accord qu'il faut faire attention aux fuites mémoire car ça fait chier tout le monde. Mais je persiste à penser qu'une personne n'a pas forcément à penser à "tout" comme elle fait une appli "toute petite et sans quelqu'un pour payer". Après, si quelqu'un paye parce que ça vaut le coup… Perso, le mec qui me fait du code "super secure" pour un prototype par exemple "parce qu'il faut toujours bien coder", je le paye moitié moins car 50% du temps est pour son plaisir (soit l'affaire prend et j'ai des sous pour refaire une passe "plus propre" après quelques refactoring, soit ça part à la poubelle et on s'en fout du realloc à NULL)
Ce n'est pas le soucis non plus. Personne n'a dit, il me semble, qu'il ne fallait surtout pas le faire. Perso, ce que j'ai dit c'est que c'est pas le plus important (ça crashe, ça libère tout et tu as vraiment des problèmes énormes sur ton OS pour n'avoir rien à foutre de ce programme "à la con". On ne parle toujours pas de fuite mémoire). Envoie un patch, tu as fait le boulot. Mais je trouve limite de demander que le code pour un programme "à la con" soit 100% parfait surtout si on ne paye rien (oui toujours l'argent… Si vous acceptez de travailler gratos, faites-moi signe)
C'est comme la sécurité : pas la peine de faire une triple authentification pour accéder à des données non sensibles. Il faut savoir s'adapter suivant l'importance de la chose. Dire "il faut toujours faire", c'est un peu gros.
[^] # Re: Chaque amélioration compte
Posté par ahuillet (site web personnel) . Évalué à 5.
Ce genre de "robustesse" a effectivement un coût, ce que pas mal de commentateurs semblent ignorer. Pour un prototype c'est carrément contre-productif de faire des vérifications de ce genre, mais c'est parfois également vrai sur des logiciels de production. Ceux qui ont développé par exemple dans Catia en savent quelque chose : vérifier si le pointeur est NULL avant chaque utilisation, ça a un coût en temps de développeur. (Cela a également un coût en temps d'exécution, qui n'est pas négligeable en C++ car on n'a pas de JIT pour éliminer ces NULL-checks.)
La question qui se pose c'est "est-ce que l'amélioration vaut le temps qu'elle coûte" (comme toujours en ingénierie logicielle), et pour des programmes non critiques la réponse est non sans hésiter. Lorsqu'un développeur passe son temps à écrire de la gestion d'erreur-qui-n'arrivera-pas, il ne fait pas autre chose de plus productif.
Concernant ce journal on est tout simplement dans le ridicule. Si realloc() returne NULL, ce qui n'arrive essentiellement jamais sous Linux, le programme va crasher (ce que Conky fait assez souvent par ailleurs). C'est un comportement tout à fait correct.
[^] # Re: Chaque amélioration compte
Posté par Zenitram (site web personnel) . Évalué à 2.
Je crois surtout qu'il y a pas mal de commentateurs qui programment de temps en temps, et "ont le temps". A moins qu'ils disent des choses qu'ils ne font pas (qui montre son code?). Mais je constate quand même qu'en ce samedi on a plus de monde qui "assume" et dit que oui, c'est une connerie de gérer les malloc/realloc à NULL. Ouf! Ca fait du bien de lire ça, plus réaliste.
[^] # Re: Chaque amélioration compte
Posté par Antoine . Évalué à 2.
Le temps, ça se prend, que ce soit pour les tests unitaires ou la gestion d'erreur. Mais bon, c'est sûr que c'est pas l'idéal si le but est de finir mentionné dans http://thedailywtf.com/
[^] # Re: Chaque amélioration compte
Posté par philou . Évalué à 3.
Tu as une façon curieuse de voir le problème, compte tenu du contexte :)
On ne parle pas des applications que certains d'entre nous doivent maintenir quand ils sont au travail mais d'un logiciel libre dont les patchs peuvent être fournis par la communauté. Selon le temps et les compétences de chacun, il est probable que des petits patchs de ce genre soient produits et je dis simplement qu'il ne faut pas hésiter à les pousser si le hasard fait qu'on passe par là.
Hors sujet ;) Je suis passé vite sur certains commentaires mais il me semble que personne n'exige cela. Pas moi en tout cas. D'ailleurs je n'exige rien, j'encourage simplement la correction de ces petits problèmes souvent délaissés car je pense qu'il est préférable de corriger en 10 secondes plutôt que de se poser la question pendant 10 minutes. Ça permet d'aller dans le bon sens. Pour ce qui est d'un travail rémunéré, le problème est autre. Pour ce qui est d'un travail plus consommateur en temps, le problème est autre.
Pour finir, je préciserais que mon commentaire traitait des petites erreurs ou améliorations possibles et non exclusivement de ce problème.
[^] # Re: Chaque amélioration compte
Posté par Etienne Bagnoud (site web personnel) . Évalué à 5.
Le problème de cette approche prototype, c'est qu'il ait de grand risque que la phase de mise au propre passe par une réécriture complète. Et là tous les bénéfices du prototype vite fait sont perdus.
De plus la phase de prototype, il y a moins de pression donc on peut prendre un peu plus de temps. Par contre avant la version finale pour la mise en production, c'est le stress, donc la mise au propre est secondaire. Et c'est pour ça qu'on a tant de logiciel en version "stable" qui ne sont rien d'autre que des bétas voir des alphas. Mais dans le monde logiciel, c'est facile de le faire, il n'y a aucune responsabilité.
En prototypage, on peut ne pas faire la gestion d'erreur, mais la prévoir. Ça coûte pas beaucoup de temps et ça permet de se concentrer sur le fonctionnement :
Et quand le temps est disponible, c'est plus facile de mettre au propre :
grep TODO *
.Mais c'est vrai que dans des projets, le rapport temps/propreté peut poser problème, particulièrement dans les petites structures.
"It was a bright cold day in April, and the clocks were striking thirteen" - Georges Orwell
[^] # Re: Chaque amélioration compte
Posté par Antoine . Évalué à 4.
Surtout, l'expérience enseigne qu'un « prototype » finit bien souvent utilisé en production, parce que tout recoder est une perte de temps quand on a un truc qui marche.
# sprintf et arithmétique de pointeurs
Posté par Krunch (site web personnel) . Évalué à 7.
Moi c'est surtout cette ligne là qui me fait dresser les poils de la barbe :
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.