| | koala01 | Posté le 23/05/2006 @ 13:23 | Astucien
4715 Messages
| Salut,
J'essaye déseperément de créer un gestionnaire de mémoire pour le débuggage d'application…
Son but est simplement de garder une trace des allocations de mémoire et de leur libération.
Pour ce faire, je crée une classe, transformée en singleton pour l'occasion, dont le membre principal est une map prenant en clé les pointeurs alloués et en valeur une structure reprenant les informations utiles sur le pointeur (entre autre, la taille et le fait que ce soit un tableau ou non)…
Cette classe contient trois méthodes puliques, dont voici les codes, en vous faisant grâce des détails insignifiants pour résoudre mon problème… bien qu'abondemment commenté pour vous permettre de comprendre le but du code…:
-GetInstance(void) qui permet de récupérer l'instance du singleton
[code]
CManagerMemoire & CManagerMemoire::GetInstance()
{
static CManagerMemoire InstanceManager;
return InstanceManager;
}[/code]
-Alloue(size_t, booléen) qui permet d'allouer un pointeur et de l'inclure dans la map
[code]void * CManagerMemoire::Alloue(std::size_t taille, bool tableau)
{
//création d'un nouveau bloc à insérer dans la map
Bloc nouveau;
nouveau.Taille=taille;
nouveau.Tableau=tableau;
try
{
//déclaration et allocation du nouveau pointeur
void *ptr;
if((ptr=malloc(taille))==NULL)
//qui jette une exception si elle échoue
throw std::bad_alloc();
//insertion du bloc dans la map avec le pointeur en clé
Allocations[ptr]=nouveau;
//un affichage de base de la réussite
std::cout<<"allocation de "<<taille<<" octets pour "<<ptr<<std::endl;
return ptr;
}
catch(...)
{
//new doit jeter l'exception bad_alloc() s'il échoue
std::cout<<"erreur d'allocation"<<std::endl;
system("PAUSE");
throw std::bad_alloc();
}
}[/code]
et
-Libere(pointeur, booleen) qui pemet de libérer le pointeur et de supprimer son occurence dans la map…
[code]
void CManagerMemoire::Libere(void *ptr, bool tableau)
{
//récupération du pointeur dans la map
MapAlloc::iterator i=Allocations.find(ptr);
try
{
//on n'est pas content si le pointeur ne fait pas partie de ceux qui sont gérés
if(i==Allocations.end())
throw std::invalid_argument("pointeur non gere par le manager");
//on se simplifie la vie, et on vérifie si on ne fait pas d'erreur
//d'appel de delete/delete[] par rapport au new/new[] utilisé
Bloc retrait=i->second;
if(retrait.Tableau!=tableau)
throw std::invalid_argument("erreur new delete[]/new[] delete");
//un affichage de base
std::cout<<"liberation de "<<ptr<<std::endl;
//suppression de l'occurence dans la mat
Allocations.erase(ptr);
//libération définitive du pointeur
free(ptr);
}
catch(std::invalid_argument &e)
{
std::cout<<e.what()<<std::endl;
system("PAUSE");
throw e;
}
}[/code]
J'ai enfin surchargé globalement new, new[], delete et delete[] de manière à ce qu'ils appellent les méthodes correspondante (Alloue pour new et new[], Libere pour delete et delete[]) de la classe sous la forme de
[code]
inline void* operator new(std::size_t taille)
{
return CManagerMemoire::GetInstance().Alloue(taille, false);
}
inline void* operator new[](std::size_t taille)
{
return CManagerMemoire::GetInstance().Alloue(taille, true);
}
inline void operator delete(void *ptr)
{
CManagerMemoire::GetInstance().Libere(ptr, false);
}
inline void operator delete[](void *ptr)
{
CManagerMemoire::GetInstance().Libere(ptr, true);
}
[/code]
Le problème que je rencontre, c'est que tous les essais que je fais fontctionnent sans aucun problème… du moment que j'essaie d'utiliser new[] et delete[] (et ce, même si je fais un new type[1]) alors que l'application ne s'initiallise meme pas correctement quand j'essaie de faire un new simple…
Quelqu'un aurait-il une idée de la manière de résoudre ce problème[question]
Merci d'avance [chinois]
| | |
| |
| Publicité |
|
| | breizhbugs | Posté le 23/05/2006 à 15:28 | Astucien
3001 Messages
| Salut,
Juste pour dire de mettre le code qui te sert a faire des tests. | | | | | koala01 | Posté le 23/05/2006 à 15:55 | Astucien
4715 Messages
| Ben, c'est tout simple:
un fichier entete "enabledebug.h" construit en
[code]
//a commenter pour annuler le tout
#define DEBUG
#ifdef DEBUG
#ifndef ENABLEDEBUG_H
#define ENABLEDEBUG_H
//inclusion pour avoir std::size_t
#include <iostream>
//inclusion du gestionnaire de mémoire
#include "cmanagermemoire.h"
inline void* operator new(std::size_t taille)
{
return CManagerMemoire::GetInstance().Alloue(taille, false);
}
inline void* operator new[](std::size_t taille)
{
return CManagerMemoire::GetInstance().Alloue(taille, true);
}
inline void operator delete(void *ptr)
{
CManagerMemoire::GetInstance().Libere(ptr, false);
}
inline void operator delete[](void *ptr)
{
CManagerMemoire::GetInstance().Libere(ptr, true);
}
#endif //ENABLEDEBUG_H
#endif //DEBUG
[/code]
et dans le fichier principal
[code]
//les classiques
#include <cstdlib>
#include <iostream>
using namespace std;
//activation du debuggage
#include "enabledebug.h"
int main(int argc, char *argv[])
{
//creation de l'instance du gestionnaire de mémoire;
CManagerMemoire &gestmem=CManagerMemoire::GetInstance();
(...)
}
[/code]
alors sont OK les codes basés sur
[code]
struct mastruct{
(...)
};
mastruct *obj1=new mastruct[1];
mastruct *obj1=new mastruct[n];//ou n est n'importe quel entier
int *entier=new int[1];
int *entier=new int[n];
char *caractere=new char[1];
char *caractere=new char[n];
n_importe_quel_type *un_nom=new n_importe_quel_type[kkechose];
[/code]
Le delete[] fonctionne alors également très bien...
foirent systématiquement les codes basés sur
[code]
mastruct *obj1=new mastruct;
int *entier=new int;
char *caracter=new char;
n_importe_quel_type *un_nom=new n_importe_quel_type;
[/code]
Je ne suis pas en mesure de tester le delete… simplement parce que l'application foire à l'initialisation bien avant que le new ne soit lancé…
La compilation et le linking ne présentent aucun problème, mais, à l'exécution, meme la création de l'instance du gestionnaire de mémoire ne va pas à son terme.
Quand on rajoute un fichier de sortie ("fuitesmemoire.log"), le fichier est créé, mais, alors que l'on demande d'y écrire un "titre" dans le constructeur du gestionnaire de mémoire, l'application s'arrete sans meme effectuer cette écriture… | | | | | AlexPrince | Posté le 23/05/2006 à 16:05 | Petit astucien
398 Messages
| C'est absolument illisible. Les tags de code sont absolument monstrueux et devraient être changés. J'te propose de coller ton code là, de peser sur le bouton paste et de nous envoyer le lien.
http://www.code-dynasty.net/paste/ | | | | | koala01 | Posté le 23/05/2006 à 16:22 | Astucien
4715 Messages
| AlexPrince a écrit :
C'est absolument illisible. Les tags de code sont absolument monstrueux et devraient être changés. J'te propose de coller ton code là, de peser sur le bouton paste et de nous envoyer le lien.
http://www.code-dynasty.net/paste/
Avec quoi tu viens toi[question][question][devil][feroce]
Je suis tout à fait d'accord avec le fait que de ne pas pouvoir formater l'apparence d'un code quand on utilise [ code ][ / code ] rend les chose beaucoup plus difficile à suivre, mais quel nom est plus compréhensible pour une structure que mastruct, pour un entier que entier, ou pour un caractere que caractere quand il s'agit de donner un exemple de code [question]
Si tu n'es pas capable de comprendre qu'un commentaire n'a d'intéret que quand il précède ce qu'il commante, je ne pourrai rien faire pour toi… d'autant plus que le code est en lui meme suffisemment indenté pour savoir ce qui se relie à quoi… Mais ne viens alors jamais me demander de relire un de tes codes si tu ne travailles pas comme cela…
Si au moins ta remarque était constructive, on aurait pu discuter entre gens civilisés, mais, encore une fois, parce que l'on a le malheur de rentrer dans le moule (très mauvais au demeurant) que souhaite MON SIEUR, voilà qu'il se met à critiquer sans raison… | | | | | koala01 | Posté le 23/05/2006 à 16:29 | Astucien
4715 Messages
| Ce coup de sang étant passé, si quelqu'un souhaite voir le code en entier, et avec une certaine "coloration synthaxique", il trouvera l'exportation au format HTML des différents fichier [url="http://koala01.free.fr/gestmem"]==>ICI<==[/url] | | | | | breizhbugs | Posté le 23/05/2006 à 16:52 | Astucien
3001 Messages
| [hello]
Je suis pas sur mais je pense que c'est parce que
"inline void* operator new(std::size_t taille)"
n'as pas de taille par defaut?
D'ailleurs quand tu fais "mastruct *obj1=new mastruct;", comment le new fait pour connaitre la taille a allouer, cad la taille en byte de mastruct?
| | | | | koala01 | Posté le 23/05/2006 à 17:14 | Astucien
4715 Messages
| C'est là que tu te trompes…
En fait, l'opérateur "new" est lui meme une surcharge de (type)malloc(sizeof(type)) … qui, pour etre précis, commence par allouer la mémoire grace à malloc puis appelle le constructeur de ta classe (ton type) pour placer les différents éléments à leurs places respectives…
La taille est donc implicitement gérée par new, grace au fait que tu fournis un type qui lui a une taille connue…
La meilleure preuve en est que, si tu crées un projet console tout bete avec le code que je fournis, si tu demande un new mastruct[n] tu verra qu'il alloue effectivement n fois (taille d'un entier+ taille de 10 caractères) (autrement dit n fois 16 octets)…
Le problème est que cela fonctionne sans problème tant que j'essaye d'allouer des tableaux sur ma structure (ma classe ou n'importe quel type connu par le programme au moment de la tentative d'allocation), mais que cela foire systématiquement quand il s'agit d'allouer un seul objet de ce type… (du moins, si je n'utilise pas new montype[1])
Et pourtant, il n'y a aucune raison à cela… ou du moins, je n'arrives pas à en déterminer la raison…
Maintenant, peut etre tout simplement mon compilo qui bug sur ce coup là…
Modifié par koala01 le 23/05/2006 17:22 | | | | | koala01 | Posté le 23/05/2006 à 18:20 | Astucien
4715 Messages
| Si tu es intéressé par le fait de voir le fonctionnement en entier (à ceci près qu'il faut encore gérer quelques erreurs, comme l'impossiblité d'ouvrir le fichier de log), tu le code final [url="http://koala01.free.fr/gestmemfinal"]==>ICI<==[/url] | | | | | breizhbugs | Posté le 23/05/2006 à 21:48 | Astucien
3001 Messages
| Salut,
Bon d'apres mes tests:
- aucun de tes new ne sont appelées (j'ai mis des std::cerr un peu partout en fait).
- sinon quand on fait un log file, on ouvre, on ecrit et on ferme le fichier dans une seule et meme fonction, car si crash quand le fichier est ouvert, on perd les données il me semble.
- j'ai une floppé d'appel a delete alors que c'est censee etre delete[], aucun appel a new! | | | | | koala01 | Posté le 23/05/2006 à 23:49 | Astucien
4715 Messages
| Alors, il y a un sérieux problème…
Soit parce que tu aurais commenté le "#define DEBUG" (première ligne du fichier enabledebug.h), soit parce qu'il n'est purement et simplement pas pris en compte lors de la compilation…
Avec dev-c++, il faut demander de compiler tous les fichiers apres avoir rajouté ce fichier au projet, c'est peut etre de là que ca vient…(car je t'assure que chez moi, les appels à new sont bien envoyé vers la classe CManagerMemoire [clindoeil])
En C, tu as raison, il vaut mieux travailler avec le fichier en une seule fois… En C++, le besoin est beaucoup moins impératif grâce au fait que la classe ofstream est très particulièrement sécurisée…
La meilleure preuve est que, si tu lance l'application juqu'au premier "appuyez sur une touche",tu peux parfaitement ouvrir le fichier créé avec un autre éditeur de textes…
Ceci dit, il semblerait que ce ne soit pas le new qui pose problème, mais le delete…
en effet l'utilisation de new avec delete[] nous envoie l'erreur (ce qui est logique), l'utilisation de new[] avec delete[] fonctionne parfaitement, mais dés que l'on essaye d'utiliser delete (que ce soit avec new ou new[], à bon escient ou non), ca foire…
Je pourrais donc me tourner vers une solution "pis aller", mais elle ne convaint pas…
En effet, je pourrais décider de supprimer l'implémentation du inline void delete(void *ptr) et d'utiliser systématiquement delete[] pour libérer les pointeurs.
Il "suffirait" pour cela que je ne lance pas l'exception invalid_argument dans libere()…
En effet, d'après mes lecture, il est tout à fait légal d'utiliser delete[] alors que l'on a utilisé new…
Le problème est alors qu'aucune utilisation de delete ne sera prise en compte par le gestionnaire de mémoire, et donc qu'il indiquera des fuites qui n'existent pas…
Comme je le saurais, je pourrais m'en accomoder, mais je perdrais énormément en "portabilité" ou en possiblités de développement en groupe…
En effet, que quelqu'un utilise (logiquement) delete apres un new ou qu'il l'utilise simplement parce qu'il "a oublier d'utiliser delete[]", et il s'étonnera "d'avoir une soi disant fuite mémoire alors qu'il a correctement tout libéré"… | | | | | AlexPrince | Posté le 24/05/2006 à 05:39 | Petit astucien
398 Messages
| koala01 a écrit :
AlexPrince a écrit :
C'est absolument illisible. Les tags de code sont absolument monstrueux et devraient être changés. J'te propose de coller ton code là, de peser sur le bouton paste et de nous envoyer le lien.
http://www.code-dynasty.net/paste/
Avec quoi tu viens toi[question][question][devil][feroce]
Je suis tout à fait d'accord avec le fait que de ne pas pouvoir formater l'apparence d'un code quand on utilise [ code ][ / code ] rend les chose beaucoup plus difficile à suivre, mais quel nom est plus compréhensible pour une structure que mastruct, pour un entier que entier, ou pour un caractere que caractere quand il s'agit de donner un exemple de code [question]
Si tu n'es pas capable de comprendre qu'un commentaire n'a d'intéret que quand il précède ce qu'il commante, je ne pourrai rien faire pour toi… d'autant plus que le code est en lui meme suffisemment indenté pour savoir ce qui se relie à quoi… Mais ne viens alors jamais me demander de relire un de tes codes si tu ne travailles pas comme cela…
Si au moins ta remarque était constructive, on aurait pu discuter entre gens civilisés, mais, encore une fois, parce que l'on a le malheur de rentrer dans le moule (très mauvais au demeurant) que souhaite MON SIEUR, voilà qu'il se met à critiquer sans raison…
Non mais... ta gueule... Je parlais du formatage du forum, pas de ton code.
[code]class ZeroException {
public:
ZeroException() { }
};
void * CManagerMemoire::Alloue(std::size_t taille, bool tableau)
{
// ...
try
{
if(taille == 0) throw(ZeroException());
// ...
}
catch(ZeroException& ze) {
taille = 1;
throw();
}
catch(...) {
// ...
}
}[/code]Essaie ça. | | | | | koala01 | Posté le 25/05/2006 à 13:17 | Astucien
4715 Messages
| Non mais... ta gueule... Je parlais du formatage du forum, pas de ton code.
[code]class ZeroException {
public:
ZeroException() { }
};
void * CManagerMemoire::Alloue(std::size_t taille, bool tableau)
{
// ...
try
{
if(taille == 0) throw(ZeroException());
// ...
}
catch(ZeroException& ze) {
taille = 1;
throw();
}
catch(...) {
// ...
}
}[/code]Essaie ça.
Hé, ho, tu ferais bien de rester un tout petit peu poli…
Si pas vis à vis de moi, car je l'ai peut etre mérité, au moins vis à vis des responsables du forum qui sont déjà bien gentils de mettre un espace de discution à notre service…
Si les capacités du forum ne te plaisent pas, sache qu'on ne te retient absolument pas…
J'espérais, visiblement à tord qu'apres la dernière explication par message privé d'il y a pres d'un an, tu aurais un peu évolué, mais visiblement c'était encore te faire trop d'honneur…
Mais tu te fourres le doigt dans l'oeil si tu crois que je vais me laisser marcher sur les pieds par un sale petit gamin de m[censure] qui n'est même pas capable de supporter qu'on lui réponde sur le ton qu'il a lui meme utilisé pour parler alors qu'on ne l'attaquait meme pas à ce moment là…
En plus, sache que new doit renvoyer bad_alloc s'il échoue, et non une quelconque zeroexception.
Sans compter que si tu avais pris un tout petit peu la peine de lire les différents codes que j'ai pris la peine de mettre en ligne, tu aurais remarqué que ce que tu me propose, c'est exactement ce qui est fait, les erreurs en moins…
Ni le fait que, si tu avais un été un peu moins occupé à te regarder le nombril en te demandant pourquoi je t'agressais en réaction à ta propre agressivité, tu aurais vu que le porblème n'était pas au niveau de new mais bien au niveau de delete… Modifié par koala01 le 25/05/2006 13:18 | | | | | koala01 | Posté le 25/05/2006 à 13:27 | Astucien
4715 Messages
| breizhbugs==> (avec toi, au moins, il y a moyen de parler en gens civilisés [clindoeil])
Ta remarque concernant le fichier log m'a incité à revoir un peu la manière dont je le gérais…
J'ai donc décidé de ne pas mettre le fichier log en tant que membre de la classe, et de modifier quelques peut les structures utilisées (et les méthodes)…
Le résultat se trouve[url="http://koala01.free.fr/gestmemfinal2"]==>ICI<==[/url] et *semble* fonctionner pour tous les cas (new, new[], delete, delete[] et avec erreur new[]delete/new delete[])
Il ne me reste plus qu'à essayer de la maltraiter un peu dans le cadre d'un projet un peu plus complexe [clindoeil]…
Je te remercie grandement du soutien et des conseils que tu as pu m'apporter[clindoeil] | | | | | breizhbugs | Posté le 25/05/2006 à 15:07 | Astucien
3001 Messages
| Salut koala,
Je te trouve un peu dur avec alex: c'est pas parce que l'on apprecie pas quelques fonctionnalités du forum, que l'on n'apprecie pas le boutot des modos.
La partie prog du forum etant assez peu fréquentée, si le peu de participants reguliers qui y vient se prends le choux c'est autant fermer cette section.
Enfin, on ne peut pas connaitre le mode de fonctionnement de toutes les APIS de tous les languages, alors quand quelqu'un emet une suggestion qui va a l'encontre d'un mode de fonctionnement precis, c'est pas la peine de lui "rentrer dans le lard" non plus. (quand je demande 'D'ailleurs quand tu fais "mastruct *obj1=new mastruct;", comment le new fait pour connaitre la taille a allouer, cad la taille en byte de mastruct?
' et que tu commence à me repondre par "C'est là que tu te trompes…", ca donne pas trop envie de repondre(meme si tu as detailler le fonctionnement plus en detail apres).
Bon je DL le code et je le teste un peu plus tard.
Sinon une question: connais tu les 'CComPtr' sous windows qui sont des pointeurs intelligents qui sont encapsulé dans une classe. Pourquoi ne pas avoir fait un truc dans le genre?
a+ | | | | | AlexPrince | Posté le 25/05/2006 à 16:28 | Petit astucien
398 Messages
| Le problème est que cela fonctionne sans problème tant que j'essaye d'allouer des tableaux sur ma structure (ma classe ou n'importe quel type connu par le programme au moment de la tentative d'allocation), mais que cela foire systématiquement quand il s'agit d'allouer un seul objet de ce type… (du moins, si je n'utilise pas new montype[1]) Et bien sûr, je devais déduire que le problème était avec delete. Que suis-je bête...
Pour ce qui est de ma suggestion, je sais très bien que new retourne bad_alloc quand il échoue... Il ne retourne 0 que si tu spécifies new(nothrow).
À moi de te renvoyer la balle maintenant: si tu avais lu mon code quelque peu, tu aurais remarqué que je n'ai pas testé la valeur retournée par new mais plutôt la variable 'taille'. En effet, si tu passes 0 à malloc() tu obtiens un comportement indéfini qui pourrait très facilement être la cause d'un crash, d'où mon test.
Edit: Petit commentaire en passant. Si tu ne sais pas écrire en anglais, ne fait pas semblant. Des trucs comme 'ManagerMemoire' ça fait pas très chic vois-tu. Utilise juste l'anglais ou juste le français parce que pour l'instant t'as l'air d'un clown avec ton code mi-anglais mi-français. 'GestionnaireMemoire' ou 'GestionMemoire' ou même encore 'GestionMem' feraient très bien l'affaire, ou alors, 'MemManager'.
Continue comme ça mon champion.. [crazy] Modifié par AlexPrince le 25/05/2006 16:32 | | | | | koala01 | Posté le 25/05/2006 à 17:32 | Astucien
4715 Messages
| breizhbugs a écrit :
Salut koala,
Je te trouve un peu dur avec alex: c'est pas parce que l'on apprecie pas quelques fonctionnalités du forum, que l'on n'apprecie pas le boutot des modos.
Vois tu, le problème est que j'ai survolé suffisemment de sujets sur lesquels alexprince réagit pour savoir qu'il est systématiquement tres agressif dans ses réponses, et qu'il ne supporte pas que l'on puisse lui en faire la remarque (ce qui était le sujet de la correspondance en message privé, et dans laquelle j'avais, soi dit en passant, mis énormément d'eau dans mon vin…)
La partie prog du forum etant assez peu fréquentée, si le peu de participants reguliers qui y vient se prends le choux c'est autant fermer cette section.
Sur ce point, je suis tout à fait d'accord avec toi…
La seule chose que je rajouterai avant de clore le sujet, ces que certaines personnes feraient bien de respecter un tant soit peu les intervenants du forums s'ils veulent etre respecter en retour.
Enfin, on ne peut pas connaitre le mode de fonctionnement de toutes les APIS de tous les languages, alors quand quelqu'un emet une suggestion qui va a l'encontre d'un mode de fonctionnement precis, c'est pas la peine de lui "rentrer dans le lard" non plus. (quand je demande 'D'ailleurs quand tu fais "mastruct *obj1=new mastruct;", comment le new fait pour connaitre la taille a allouer, cad la taille en byte de mastruct?
' et que tu commence à me repondre par "C'est là que tu te trompes…", ca donne pas trop envie de repondre(meme si tu as detailler le fonctionnement plus en detail apres).
Excuse moi pour cet exces d'agressivité absolument injustifié [clindoeil][rougir]
Bon je DL le code et je le teste un peu plus tard.
Sinon une question: connais tu les 'CComPtr' sous windows qui sont des pointeurs intelligents qui sont encapsulé dans une classe. Pourquoi ne pas avoir fait un truc dans le genre?
a+
Je pourrais effectivement décider d'utiliser les pointeurs intelligents (plutot ceux de la STL, alors, car je souhaites que le projet dans lequel cela s'insérera soit le plus portable possible, ce qui fait que je ne voudrais pas utiliser quelque chose qui ne soit accessible que sous un système donné, raison pour laquelle je prévois de supprimer les appels à system("PAUSE")…)
Mais maintenant que la classe *semble* fonctionner, je vais me faire un plaisir de l'utiliser…
Alexprince==>
AlexPrince a écrit :
Le problème est que cela fonctionne sans problème tant que j'essaye d'allouer des tableaux sur ma structure (ma classe ou n'importe quel type connu par le programme au moment de la tentative d'allocation), mais que cela foire systématiquement quand il s'agit d'allouer un seul objet de ce type… (du moins, si je n'utilise pas new montype[1]) Et bien sûr, je devais déduire que le problème était avec delete. Que suis-je bête...
(c'est toi qui dit que tu es bete… je serai suffisemment bon pour décider de ne pas dire mon avis sur le sujet (car, si tu avais lu les autres messages… enfin bon…)
Pour ce qui est de ma suggestion, je sais très bien que new retourne bad_alloc quand il échoue... Il ne retourne 0 que si tu spécifies new(nothrow).
À moi de te renvoyer la balle maintenant: si tu avais lu mon code quelque peu, tu aurais remarqué que je n'ai pas testé la valeur retournée par new mais plutôt la variable 'taille'. En effet, si tu passes 0 à malloc() tu obtiens un comportement indéfini qui pourrait très facilement être la cause d'un crash, d'où mon test.
Là ou tu as tout à fait raison, et je vais d'ailleurs me dépécher de modifier le code, c'est qu'il faut prévoir le cas où l'on essayerais effectivement d'allouer une taille nulle pour éviter les comportement aléatoires…
Edit: Petit commentaire en passant. Si tu ne sais pas écrire en anglais, ne fait pas semblant. Des trucs comme 'ManagerMemoire' ça fait pas très chic vois-tu. Utilise juste l'anglais ou juste le français parce que pour l'instant t'as l'air d'un clown avec ton code mi-anglais mi-français. 'GestionnaireMemoire' ou 'GestionMemoire' ou même encore 'GestionMem' feraient très bien l'affaire, ou alors, 'MemManager'.
Tu vas encore croire que je t'agresse de manière non justifiée, mais, à tout hasard, manager est tout à fait un terme francais également…
Peut etre pas au canada, mais il est bel et bien dans mon Dictionnaire…
Ceci dit, j'aurais effectivement pu décider d'un terme plus simple pour la classe
Continue comme ça mon champion.. [crazy]
Si je devais répondre à cela, je m'énerverais surement encore (mais de manière tout à fait injustifiée, n'est-ce pas [quetion])
Je préfères donc laisser les autres juges… | | | | | AlexPrince | Posté le 25/05/2006 à 23:51 | Petit astucien
398 Messages
| Manager est un anglicisme... Mais si tu y tiens... 'GetInstance' est complètement anglophone. | | | | | koala01 | Posté le 26/05/2006 à 02:55 | Astucien
4715 Messages
| AlexPrince a écrit :
Manager est un anglicisme... Mais si tu y tiens... 'GetInstance' est complètement anglophone.
Alors, je vais essayer d'être clair tout en te parlant tout aussi calmement que possible…
Oui, manager est un anglicisme, mais, afin d'améliorer ta culture générale, il faut savoir que beaucoup d'anglicismes sont, très souvent, à la base, des mots français récupérés par les anglais, avant d'etre des mots anglais…
Je sais que le mot d'origine date, le plus souvent du Moyen-Age, mais les langues vivantes ont de tous temps récupéré des termes dans d'autres langues, et ce n'est pas pres de changer…
Le malheur, si tu veux voir les choses sous cet angle, c'est qu'actuellement la langue véhiculaire majeure est l'anglais, et qu'il est donc logique que de nombreux emprunts y soient fait (on a encore de la chance: si les mots étaient en chinois ou en indou, on risquerait d'avoir beaucoup plus de mal [clindoeil])
Quand il s'agit, pour moi, de créer un assesseur ou un modificateur, effectivement, j'utilises sans vergogne les préfixes Get et Set, simplement parce que tout le monde comprend ce que cela veut dire, et que c'est beaucoup plus court à écrire que les équivalents francophones…
En outre, de très nombreuse EDI, meme si elles sont en francais, te proposeront de créer "les méthodes set et get" quand tu leurs demandera de créer un membre dans une classe…
Je ne vois pas vraiment ce qu'il peut y avoir de coquant là dedans…
Ensuite, effectivement, il m'arrive d'utiliser des termes clairement anglais (quoi qu'il n'y ai que GET dans Get Instance qui le soit [clindoeil]), mais, si cela t'ennuies, je ne t'obliges nullement à utiliser mes codes…
Le malheur de ta dernière intervention est que, de mon point de vue, elle a tendance à confirmer l'impression que je me fais de toi… Je me demande d'ailleurs pourquoi j'ai bien pu prendre la peine d'y répondre… Modifié par koala01 le 26/05/2006 02:57 | | | | | breizhbugs | Posté le 26/05/2006 à 13:21 | Astucien
3001 Messages
| J'hesite:
[img]http://yelims5.free.fr/Sport/PingPong.gif[/img]
ou
[img]http://yelims5.free.fr/Sport/_Escrime.gif[/img]
ou
[img]http://yelims5.free.fr/Sport/Boxe.gif[/img]
(toujours pas tester le code...) | | | | | breizhbugs | Posté le 26/05/2006 à 20:37 | Astucien
3001 Messages
| re,
Bon j'ai testé et ca plante!
la memoire alloué dans le main est correctement liberer semble t il mais lors du rapport dans le destructeur il indique:
*** 004508A8 élément de 16 octets alloué dans main.cpp ligne 16 libere -> normal
*** 004501C8 tableau de 4522480 octets alloué dans ÐE ÐE ØE ØE àE àE èE èE ðE ðE øE øE E E E E E E E E E E (E (E ... -> pas normal. (un bloc.fichier pas initialisé?)
Je ne m'y connais pas du tout en Map truc muche donc sais pas trop comment ca fonctionne pour modifier.
Sinon une question je suis pas sur:
[code]
void * CManagerMemoire::Alloue(std::size_t taille, bool tableau,
const std::string &fichier, int ligne)
{
Bloc nouveau;
nouveau.Taille=taille;
nouveau.Tableau=tableau;
nouveau.Fichier=fichier;
nouveau.Ligne=ligne;
nouveau.Libere=false;
try
{
void *ptr;
if((ptr=malloc(taille))==NULL)
throw std::bad_alloc();
Allocations[ptr]=nouveau;
std::cout<<"allocation de "<<taille<<" octets pour "<<ptr<<std::endl;
//std::cin.get();
return ptr;
}
catch(...)
{
std::cout<<"erreur d'allocation"<<std::endl;
//system("PAUSE");
throw std::bad_alloc();
}
}
[/code]
Concernant "Bloc nouveau", il appartient a la fonction et est donc liberer a la fin de celle ci. Cela suppose donc que "Allocations[ptr]=nouveau;" recopie nouveau dans le tableau c'est bien ca?
Modifié par breizhbugs le 26/05/2006 20:43 | | | | | koala01 | Posté le 27/05/2006 à 00:15 | Astucien
4715 Messages
| La std::map est, en fait, le pendant des vecteurs et autres piles et files (plus près des vecteurs, ceci dit [clindoeil])…
Il s'agit d'un tableau associatif clé<-->valeur, et tu as parfaitement compris le fait que NomDeMap[cle]=valeur avait pour but de recopier valeur dans le tableau en lui associant la clé cle (qui n'est ici rien d'autre que l'adresse du pointeur que l'on vient d'allouer [clindoeil][langue]…)
(désolé, le lien est en anglais, mais, dés que j'aurai un équivalent francais, tu l'auras [url="http://www.sgi.com/tech/stl/Map.html"]==>les infos sont ici<==[/url])
C'est vraiment bisard que ca plante chez toi, alors que cela fonctionne tout à fait correctement chez moi…
J'aimerais beaucoup comprendre pourquoi cela fonctionne si bien chez moi et pas chez toi…
Quel compilateur utilises tu, de manière à me faire une idée [question] | | | | | koala01 | Posté le 27/05/2006 à 00:58 | Astucien
4715 Messages
| Alors, à part le fait que j'ai supprimé certaines demande d'appuis sur une touche, je viens d'essayer de compiler le programme avec borland 6 (version entreprise)…
Il fonctionne sans aucun problème (de meme que sous dev-c++), la seule différence que j'obtiennes est le fait que, compilé avec borland, j'obtiens les lignes du log sous la forme de
*** 9459928 élément de 4 octets alloué dans C:\Documents and Settings\phil\Bureau\essai2\src\main.cpp ligne 14 libere
et que sous dev-c++, j'obiens le log sous la forme de
*** 0x3d2480 élément de 4 octets alloué dans src/main.cpp ligne 14 !!!non libéré !!!
(autrement dit, l'un avec le chemin absolu, et l'autre avec le chemin relatif)
Ne t'en fais pas trop, mais cela, je présumes que tu t'en doutes, pour les accents dans la console (les é deviennent Ù) la sortie est en fait formatée pour etre correcte dans le fichier log (et, comme tout le monde sait bien que microsoft n'est meme pas capable d'accorder sa console avec le reste du système [langue][rougir]) | | | | | AlexPrince | Posté le 27/05/2006 à 05:41 | Petit astucien
398 Messages
| Sans vouloir t'offenser... c'est ton programme qui a le problème. La console peut très bien afficher des caractères accentués et autres.
Tu dois alors utiliser wchar_t au lieu de char.
http://www.opengroup.org/pubs/online/7908799/xsh/stddef.h.html
Edit: De toutes évidence ça ne fonctionne pas mais je me souviens avoir testé un programme fait par quelqu'un d'autre qui avait été capable de faire fonctionner les accents dans la console. Modifié par AlexPrince le 27/05/2006 05:46 | | | | | breizhbugs | Posté le 27/05/2006 à 13:27 | Astucien
3001 Messages
| Re,
Avant d'envoyer une chaine sur la console(sous windows en tout cas), il faut faire un 'ansitooem' ou un truc dans le genre.
En fait j'ai modifier les operateurs new/delete pour qu'ils affichent a message genre:
[code]
inline void operator delete(void *ptr)
{
std::cout << "operator del:\t" << ptr << std::endl;
CManagerMemoire::GetInstance().Libere(ptr, false);
};
[/code]
Et il se trouve que j'ai des appels aux 'delete' bien apres la derniere instruction et apres meme que le destructeur de CmanagerMemoire soit terminé!
Je suis sous VC++ .net 2002.
Modifié par breizhbugs le 27/05/2006 13:28 | | | | | koala01 | Posté le 27/05/2006 à 16:09 | Astucien
4715 Messages
| breizhbugs a écrit :
Re,
Avant d'envoyer une chaine sur la console(sous windows en tout cas), il faut faire un 'ansitooem' ou un truc dans le genre.
En fait j'ai modifier les operateurs new/delete pour qu'ils affichent a message genre:
[code]
inline void operator delete(void *ptr)
{
std::cout << "operator del:\t" << ptr << std::endl;
CManagerMemoire::GetInstance().Libere(ptr, false);
};
[/code]
Et il se trouve que j'ai des appels aux 'delete' bien apres la derniere instruction et apres meme que le destructeur de CmanagerMemoire soit terminé!
Je suis sous VC++ .net 2002.
Oui, de fait, j'avais résolu ce problème, mais apres avoir placé le code…
Tous les liens sont maintenants prévus pour se rendre au bon endroit [clindoeil]
J'en ai d'ailleurs profité pour "écarteler" le fichiers cexceptions en plusieurs fichiers selon l'origine de l'exception qui est lancée, et pour mettre le tout dans un espace de nommage…
Hier, à la lecture d'un document très correct sur la STL, je me posais la question de savoir si ton compilateur supportait les constructeurs par défaut… Vu son "age", ce devrait etre le cas…
Il s'agit d'un document de 62 pages, en PDF, dont je ne retrouve pas le lien pour te permettre de le télécharger si tu le souhaites… S'il t'intéresse, je le tiens à ta disposition [clindoeil]
Je te remercie de l'idée de ansitooem, mais, malheureusement, il *semble* que l'instruction soit réservée à windows, et, dans de telles conditions, je préfères m'en passer (quand on se met à vouloir la protabilité [clindoeil][langue])
Dans l'ensemble (pour répondre, par la meme occasion à AlexPrince), le wchar_t ne résoudra qu'une partie des problèmes, dépendamment des locales définies pour la console, et posera en plus le problème de ne plus etre du texte "brut", car codé sur deux octets…
A mon sens, dés qu'un projet devient important, le nombre d'allocations/libérations mémoires atteind très rapidement des sommets…
L'affichage de l'ensemble de celles-ci dans une console en sortie de programme ne me semble pas *forcément* des plus adapté au travail de la personne qui est face à son clavier…
Ici, sur le programme d'exemple, avec une ou deux allocations, on peut se permettre de les montrer, surtout que cela permet de se faire une idée du fonctionnement, mais en production, la seule sortie console serait vraissemblablement plutot le rapport cumulé des fuites et non la ribambelle de celles-ci et de la suite des opérations qui y a mené…
Je suis ouvert à toute discution (constructive) sur le sujet, mais, personnellement, je préfères éplucher un tel rapport imprimé que de m'écarquiller les yeux sur une sortie console… | | | | | koala01 | Posté le 27/05/2006 à 16:20 | Astucien
4715 Messages
| Alexprince==> cela te fera peut etre plaisir de savoir qu'effectivement j'ai changé le nom de la classe… c'est devenu CGestMemoire [clindoeil] (par contre, tu risque de tiquer en voyant le nom de l'espace de nommage: "Debugging"[boom][boom]) | | | | | breizhbugs | Posté le 27/05/2006 à 18:52 | Astucien
3001 Messages
| Bon j'ai DL la nouvelle version et je testerai plus tard... | | | |
| | Haut de la page |
| | Inscrivez-vous ! |
- Posez vos questions
- Résolvez vos problèmes
- Aidez les autres
- Participez et créez vos discussions
- Dialoguez en privé avec d'autres membres
- Suivez vos sujets préférés
- Affichez les signatures des membres
|
|