cs_koala01
Messages postés16Date d'inscriptionjeudi 19 juin 2003StatutMembreDernière intervention25 mai 2006
-
24 mai 2006 à 02:52
cs_koala01
Messages postés16Date d'inscriptionjeudi 19 juin 2003StatutMembreDernière intervention25 mai 2006
-
25 mai 2006 à 13:42
Salut,
Je m'adresse à vous car je suis confronté à un problème qui me fait perdre mon latin...
Je souhaites créer un "gestionnaire de mémoire" dans le but de traquer les fuites mémoires dans une application.
Pour ce faire, j'ai créé une classe, CManagerMemoire, transformée en
singleton pour la cause, qui prend en charge la surveillance des
allocations/libérations de mémoire.
Pour ce faire, elle dispose, principalement, de trois méthodes:
<li>Getinstance qui renvoie une référence sur l'instance statique de mon gestionnaire,</li><li>Alloue(std::size_t taille,bool tableau,const
std::string& fichier,int ligne) qui prend en charge
l'allocation du pointeur et l'introduction des informations qui le
concerne dans une map</li><li>Libere(void *ptr) qui se charge de libérer le pointeur et de le supprimer de la map de controle.</li>
Pour qu'elle puisse travailler à son aise, j'ai créé dedans une
structure Bloc qui permet de garder l'ensemble des informations
que je souhaites surveiller (taille du bloc alloué, fichier et ligne où
l'allocation a lieu, s'il s'agit ou non d'un tableau).
Cest informations sont gardées, pendant leur période de validité, dans
une map dont la clé n'est autre que l'adresse du pointeur
alloué(std::map(void*, Bloc))
Pour que l'appel à cette classe soit effectué automatiquement, j'ai surchargé new,new[], delete et delete[] sous les formes de
<hr size= "2" width="100%" />inline void* operator new (std::size_t taille,const std::string &fichier, int ligne)
};
<hr size ="2" width="100%" />J'ai enfin créé un macro préprocesseur qui redéfini new pour qu'il appelle automatiquement les new précités sous la forme de
<hr size="2" width="100%" />#define new new(__FILE__,__LINE__)
<hr size="2" width="100%" />Si l'allocation se passe sans problème, qu'il
s'agisse de l'utilisation de new ou de new[], je me retrouve confronté
à une problème bisard en ce qui concerne delete...
En effet, tant que j'utilses delete[], il n'y a aucun problème (hormis,
bien sur, le fait que je fais une vérification pour savoir si c'était
ou non un tableau)
Par contre, dés que j'essaie d'utiliser delete, je me retrouve immanquablement avec une erreur de segmentation...
Je sais (ou du moins, je crois savoir...FIXME )
par mes lectures qu'il est tout à fait légal d'utiliser l'opérateur
delete[] alors que l'on a créé notre objet avec new...
La solution "de facilité" serait alors de supprimer la surcharge de
delete, de supprimer la vérification du fait qu'il s'agisse ou non
réellement d'un tableau, et d'utiliser systématiquement delete[], qui
fonctionne très bien, au lieu de delete, et ce même si new avait été
utilisé...
L'astuce, c'est que si je peux parfaitement m'arranger de cet état de
fait, principalement parce que je le saurais, cette solution ne
présente qu'un pis-aller dans le sens où, si pour une raison ou une
autre, quelqu'un vient à utiliser cette classe (soit parce qu'il la
jugeait intéressante, soit parce qu'il voudrait participer au
développement d'un projet ambitieux qui l'utiliserait)... il risque de
ne pas être au courent (ou simplement d'oublier) qu'il faut en
permanence utiliser delete[]...
Le résultat étant que, dans un premier temps il pestera dans toutes les
langues de l'arc-en-ciel "mais je l'ai pourtant libérée, cette
mémoire", et dans un deuxième temps, il n'y fera plus
attention...("mais oui, j'ai soi disant oublié de libérer la mémoire de
mon pointeur")
Bref, je préférerais me passer de cette classe plutot que de ne pas la voir entièrement fonctionnelle
J'ai essayé de la compiler aussi bien sous dev-c++(mingw sauf erreur) que sous GCC (sous linux) et le problème persiste.
Vu que ce message devient déjà kilométrique, vous trouverez le code complet ==>ici<==.
Si vous aviez la moindre idée de la raison pour laquelle ca ne veut pas
fonctionner, je vous en supplie, venez à mon secours... (toute remarque
constructive sera forcément prise en compte)
Merci d'avance
Ce qui ce conçoit bien s'énonce clairement
et les mots pour le dire vous viennent aisément
cs_koala01
Messages postés16Date d'inscriptionjeudi 19 juin 2003StatutMembreDernière intervention25 mai 2006 25 mai 2006 à 13:42
Bon, ben, je me réponds à moi meme pour le cas où quelqu'un d'autre serait intéressé...
Il *semblerait* que le problème venait du fait que j'avais mis un fichier de sortie comme membre de ma classe, et que je faisais des appels à ce fichier pour chaque opération.
J'ai modifié un peu les différentes structures et les méthodes de manière à ce que le fichier de log ne soit plus membre de la classe, mais simplement ouvert au moment où l'on souhaite effectuer une sauvegarde des opérations (en gros, quand on détruit l'instance du gestionnaire de mémoire).
Bien qu'il est préférable que je prenne le temps de maltraiter un peu la classe avant de crier victoire, le code modifié se trouve ==>ICI<== pour le cas où il pourrait intéresser quelqu'un
Ce qui ce conçoit bien s'énonce clairement
et les mots pour le dire vous viennent aisément