|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
Bonjour,
je me suis amusé a faire une bête liste chainée et je ne comprends pas pourquoi mon programme prends près de 4 Mo à la fin de l'exécution par rapport au 310 ko de départ. Si j'appelle ma fonction plusieurs fois, à la fin mon programme prends environ 4,4Mo Code :
|
||
|
|
10
|
|
|
#2 |
|
Membre Expert
![]() Développeur en systèmes embarqués Inscription : mars 2006 Messages : 763 ![]() |
Salut,
Et testmem lui-même, tu ne fais pas de free dessus? A+ Pfeuh |
|
|
00
|
|
|
#3 | ||||
|
Membre éclairé
![]() ![]() Julien SanchezÉtudiant Inscription : décembre 2012 Messages : 50 ![]() |
Dans ce programme, la mémoire allouée est correctement libérée. Il n'y a pas de fuite de mémoire ici. Si le programme occupe toujours de l'espace mémoire après avoir utilisé "free", cela provient d'une raison externe au code.
Pour s'en convaincre, on peut remplacer les appels à "malloc" et "free" par des appels à ces fonctions : Code :
Remarque 1 : Lors de la création d'un nouvel élément de liste, il serait judicieux d'initialiser son pointeur "nextChar" à la valeur "NULL". Remarque 2 : Il est inutile de passer l'adresse de la variable "i" en argument à la fonction "printf". Par exemple, cet appel à la ligne 19 : Code C :
printf ("je vais prendre de la memoire\n", &i ); Code C :
printf ("je vais prendre de la memoire\n"); Remarque 3 : Il est recommandé de tester la valeur de retour de la fonction "malloc", afin de s'assurer que l'allocation mémoire s'est bien déroulée. Elle peut en effet échouer si il n'y a plus assez de mémoire libre. Voici un exemple de code : Code C :
Remarque 4 : Il est préférable d'utiliser l'une des constantes "EXIT_SUCCESS" ou "EXIT_FAILURE" prédéfinies dans l'entête "stdlib.h" pour désigner la valeur de retour du programme. Autrement dit, dans la fonction "main", il est préférable de remplacer par Remarque 5 : En langage C, il est préférable d'écrire explicitement les arguments de la fonction "main". Autrement dit, il est préférable de remplacer par
__________________
Un logiciel est libre si vous avez le droit d'étudier son code source, de le modifier et de le redistribuer. GNU/Linux est un logiciel libre, alors que Windows et Mac OS ne le sont pas. (aide) |
||||
|
|
20
|
|
|
#4 |
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
merci pour les dernières remarques, c'est vrai que je n'ai pas fait attention aux détails car ce programme ne me sert à rien, juste a vous poser cette question existentielle de l'utilisation de la mémoire après les free
Qui trouvera LA solution ? |
|
|
00
|
|
|
#5 |
|
Expert Confirmé Sénior
![]() |
Si le comportement ne vient pas de malloc(), alors il vient de la plate-forme sur laquelle le programme tourne. Tu dois donc nous préciser l'OS, compilateur, etc.
Attention au passage, rien ne garantit que la mémoire retournée par malloc() soit initialisée à zéro: Le pointeur nextChar de ton dernier chaînon peut contenir n'importe quoi!
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant. "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?" Apparently everyone. -- Raymond Chen. Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen. |
|
|
00
|
|
|
#6 |
|
Membre éclairé
![]() Développeur informatique Inscription : mai 2011 Messages : 203 ![]() |
Arrêtez de vous prendre la tête! Les librairies de base sont fiables (bien que j'en ai également douté)
J'ai vu pas mal de questions au sujet de malloc / free / printf, et il s'avère que le problème vient toujours de l'application, et non de la librairie. Arrêtez de croire que parce que votre application a un problème, il vient de la librairie! |
|
|
00
|
|
|
#7 |
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
je tourne sur codeblocks, mon compilateur c'est gcc sur mon os: win7
c'est vrai que je n'ai pas mis à NULL le dernier pointage sur le chaînon suivant, la mise à jour est faite et non cela ne résout pas le problème. Je suis passé sous linux (ubuntu 12.10) pour étudier le comportement du programme, je suis toujours sur codeblocks et mon compilateur c'est encore gcc. Il est a noté que de base mon programme prends moins de ko. Une fois que je prends de la mémoire je passe à environ 900 Mo au lieu de 500 sous windows, le pire c'est que sous linux la mémoire ne se libère pas. Par contre si je relance plusieurs cette même fonction cela ne bouge pas en mémoire je suis toujours à 900 Mo... J'ai essayé de lancer mon programme dans le terminal et non depuis cb et cela n'a rien changé... Pour faire simple avez vous déjà vu une liste chainée ne laissant aucune trace en mémoire après avoir fait une multiple allocation? SI oui dans ce cas donnez moi le code car pour l'instant je suis dans l'impasse... |
|
|
00
|
|
|
#8 | ||||||||||
|
Expert Confirmé Sénior
![]() ![]() Frédéric Ingénieur développement logiciels Inscription : février 2006 Messages : 3 496 ![]() |
Salut
Citation:
Citation:
Citation:
Code C :
Citation:
Citation:
Citation:
Et donc peut-être que le free se comporte de la même façon. La mémoire libérée reste allouée au programme lui-même qui pourra donc la réutiliser au malloc suivant. D'ailleurs il existe (sous Windows) des utilitaires sensés scruter les programmes actifs et rendre à l'os ces zones mémoires libérées logiquement mais non physiquement...
__________________
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche. Tout ce qu'un individu reçoit sans rien faire pour l'obtenir, un autre individu a dû travailler pour le produire sans en tirer profit. Tout Pouvoir ne peut distribuer aux uns que ce qu'il a préalablement confisqué à d'autres car on n'accroît pas les biens en les divisant. Quand la moitié d'un peuple croit qu'il ne sert à rien de faire des efforts car l'autre moitié les fera pour elle, et quand cette dernière moitié se dit qu'il ne sert à rien d'en faire car ils bénéficieront à d'autres, cela s'appelle le déclin et la fin d'une nation. Dr. Adrian Rogers, 1931 |
||||||||||
|
|
20
|
|
|
#9 |
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
Merci beaucoup pour ta réponse Sve@r,
Maintenant la vrai interrogation c'est de savoir comment on libère la mémoire physiquement et non logiquement? Apparemment c'est vraiment à la charge du système d'exploitation. Si c'est bien le cas je suis tombé dans un problème bien trop complexe a mon niveau je pense. |
|
|
00
|
|
|
#10 | |||
|
Membre éclairé
![]() ![]() Julien SanchezÉtudiant Inscription : décembre 2012 Messages : 50 ![]() |
Je viens de le vérifier, le programme écrit par callsty libère correctement toute la mémoire allouée avant de se terminer.
Je ne peux malheureusement pas me procurer la spécification officielle du langage C auprès de l'organisme ISO car cela coûte environ 200 euros, je trouve cela triste. Cependant j'ai trouvé un brouillon daté de 2005 à cette adresse : www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf. Voici ma traduction de cette spécification de la fonction "free". Citation:
Je n'en suis pas sûr, mais il me semble donc que si on veut rester conforme au C standard, on ne peut pas obliger le programme à rendre au système d'exploitation de la mémoire allouée via la fonction "malloc". Car il serait possible qu'une implémentation du langage C conforme au standard ait programmé les fonctions "malloc" et "free" de façon à ce qu'elle ne restituent jamais la mémoire non utilisée au système d'exploitation. La seule solution pour libérer la mémoire serait alors de terminer le programme.
__________________
Un logiciel est libre si vous avez le droit d'étudier son code source, de le modifier et de le redistribuer. GNU/Linux est un logiciel libre, alors que Windows et Mac OS ne le sont pas. (aide) |
|||
|
|
00
|
|
|
#11 | |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Citation:
Sur la question de rendre la mémoire à l'OS. 1/ Je ne vois pas comment le formuler l'idée dans le cadre de la norme. 2/ Les problèmes de fragmentation font qu'en pratique les cas où c'est possible sont rares, donc en faire une contrainte serait difficile sans exclure des techniques d'implémentation raisonnables.
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
|
40
|
|
|
#12 |
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
Merci pour ta réponse Jean-Marc.Bourget
Dans ce cas es qu'il y a un langage ou autre extérieur au c qui puisse forcer à rendre la mémoire? Quels sont les techniques d'implémentation? Je suis insistant car sur le web je n'ai vu aucune réponses et cela manque cruellement à tout les novices comme moi. |
|
|
00
|
|
|
#13 | |
|
Membre émérite
![]() ![]() |
Bonjour,
Citation:
Bonne journée.
__________________
Récursivité en C : épidémie ou hérésie ? "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman |
|
|
00
|
|
|
#14 | |
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Citation:
Le problème est que l'OS gère la mémoire avec une granularité minimale d'une page (valeur typique: 4kb), donc tu va vouloir la découper, et pour la rendre à l'OS il faut t'assurer qu'elle soit complètement inutilisée. C'est un surcoût. Note que ce que font certains allocateurs, c'est d'utiliser des techniques différentes suivant la taille demandée, et rendre la mémoire à l'OS pour les grandes tailles d'allocation.
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|
|
|
00
|
|
|
#15 | |
|
Membre éclairé
![]() ![]() Guillaume GomezÉtudiant Inscription : mai 2010 Messages : 176 ![]() |
Citation:
|
|
|
|
20
|
|
|
#16 | |||
|
Expert Confirmé Sénior
![]() ![]() ![]() Inscription : novembre 2005 Messages : 4 970 ![]() |
Citation:
Citation:
De plus il te faudrait aussi rendre à l'OS tout ce qui précède et est libre. Citation:
Plus elle est faible, plus la taille des structures de données de l'OS utilisées pour gérer une quantité de mémoire est grande et plus il doit faire des opérations pour ce faire. Ça a un coût aussi. La tendance est plutôt à chercher à gérer de grandes pages (ce que les processeurs fournissent depuis un bon moment).
__________________
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça. |
|||
|
|
30
|
|
|
#17 | ||
|
Invité de passage
![]() Inscription : octobre 2012 Messages : 10 ![]() |
Citation:
|
||
|
|
00
|
|
|
#18 |
|
Membre éclairé
![]() ![]() Julien SanchezÉtudiant Inscription : décembre 2012 Messages : 50 ![]() |
Comme l'a suggéré Jean-Marc.Bourguet, si la façon dont malloc et free sont programmées ne convient pas, il est possible de les réécrire.
Quand on ne sait pas par où commencer, la première chose à faire est de lire leur code source et essayer de le comprendre. Pour le système d'exploitation GNU/Linux, le code source de malloc et free se trouve sur le site de la GNU C Library. On peut le lire en ligne sur le dépôt git de la glibc. On peut accéder directement au fichier source "malloc.c". Pour écrire sa propre version de malloc et free sous GNU/Linux, il est utile de lire la description des fonctions mmap et munmap, ainsi que la documentation sur la gestion de la mémoire avec la glibc. Une solution alternative serait de scinder le programme final en deux petits programmes. Le premier petit programme étant un gros consommateur de mémoire, alors que le second n'en consomme que très peu et met beaucoup de temps à s'exécuter. On commencerait par démarrer le premier petit programme, puis, une fois que celui-ci à terminé son travail, il lance le second, en lui passant en argument les résultats dont il a besoin. Voir à ce sujet la documentation de la glibc sur les processus, les descriptions des fonctions execve et system, et la communication inter-processus. Un conseil : ne pas utiliser de telles techniques d'optimisation. Surtout quand on débute.
__________________
Un logiciel est libre si vous avez le droit d'étudier son code source, de le modifier et de le redistribuer. GNU/Linux est un logiciel libre, alors que Windows et Mac OS ne le sont pas. (aide) |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com