WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 2012
-
26 janv. 2006 à 21:21
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 2012
-
28 janv. 2006 à 01:28
Tout est parti d'une simple et toute petite application console écrite pour tester la fonction GetHeapStatus en vue de l'intégrer dans un futur programme :
program Episode1; // La Menace (de la mémoire) Fantome
{$APPTYPE CONSOLE}
uses
SysUtils;
var
I64 : Int64;
begin
Writeln( 'Memoire libre : ' + IntToStr(GetHeapStatus.TotalFree) + ' octets.' ) ;
// Code
I64 := $7FFFFFFFFFFFFFFF ;
Writeln( 'Max I64 : ' + IntToStr( I64 ) ) ;
Writeln( 'Memoire libre : ' + IntToStr(GetHeapStatus.TotalFree) + ' octets.' ) ;
// Attente Appui d'une touche
Readln;
end.
Nous avons à présent notre coupable. Mais pourquoi avons nous perdu 32 octets ??? (et même plus étant donné que l'on rappelle IntToStr à la fin pour afficher la fuite de mémoire!!)
Peut on éviter cette fuite ?
Etant déjà à l'épisode 5, je n'aurais certainement pas de mal à moi aussi atteindre l'épisode 6, mais aller jusqu'à finir par un grand dénouement, là va pas falloir m'en demander trop ;)
program Episode6; // Le retour du Jedi
{$APPTYPE CONSOLE}
uses
SysUtils;
var
I64 : Int64;
MemoireDebut : Integer ;
MemoireFin : Integer ;
procedure AfficheEntier ( const s : string ; i : int64 ) ;
begin
Writeln( S + IntToStr( i ) ) ;
end ;
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 26 janv. 2006 à 22:33
Salut,
Très très interressant tous ça.
il semblerait que la fonction IntToStr alloue de la mémoire pour pouvoir faire le transtypage et que le fait d'utiliser une procedure à part pour effectuer l'affichage permet de la libérer de suite comme toute autre variable déclaré localement dans une procédure où fonction.
oh grand maitre toi qui a le savoir éclaire ma lanterne est ce que le jeune padawan est sur la voie de la sagesse
normal, car a la fin d'une fonction ou procedure, la memoire allouée pour le traitement est libérée.
<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
WhiteHippo
Messages postés1154Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 avril 20122 28 janv. 2006 à 01:28
Cirec, foxi, je suis en grande partie d'accord avec vous, tout est affaire de portée (Durée de vie) de variable MAIS ... (et oui il y a un MAIS )
Que la fonction IntToStr réserve des octets pour y stocker le résultat de la conversion, rien de plus logique. Rien à redire de ce côté là. Par contre, ce qui n'est pas normal, c'est que le compilateur ne libère pas les chaines allouées hors des fonctions et procédures lorqu'elle ne sont plus nécessaires, c'est à dire lorsque leur portée n'est plus
Portée de la chaine : Le temps de l'appel de la fonction Writeln, et c'est tout.
Hors, on s'aperçoit que la chaine de retour de IntToStr est toujours présente en mémoire, alors qu'elle ne sera plus jamais utilisée par le programme.
JE SUPPOSE qu'elle sera certainement supprimée à la fin du programme (portée globale), mais ce n'est pas normal.
L'appel de IntToStr au sein d'une procédure ou d'une fonction résoud le problème (la portée étant clairement définie, celle de la procédure ou de la fonction, bref une portée locale) Le compilateur libère donc à la fin de la fonction, les variables allouées localement.
Une autre façon de s'en convaincre, c'est d'appeller 20 fois :
Dans le second cas, on s'apperçoit, que la fuite de mémoire augmente (et c'est peu dire lorsque l'on voit la quantité de mémoire non libérée : 800 octets = 20 * 40 octets) en fonction du nombre d'appel, ce qui n'est pas le cas de la boucle, dont la fuite reste à 40 octets. (Au passage, on remarquera qu'il y a quand même 40 octets perdus )
Là encore, JE SUPPOSE que le compilateur a limité la portée de la chaine à l'intérieur de la boucle, ce qu'il n'a pas su faire dans le cas du multi appel.
Il me semble que c'est une mauvaise gestion de la libération de la mémoire allouée en fonction de la portée, et donc un bug.
Bien sur, ce sont MES SUPPOSITIONS.
Cordialement.
<HR>
Il existe 10 catégories de personne. Ceux qui connaissent le binaire et les autres...