IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Surcharge de new / delete et Memory Manager


Sujet :

C++

  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut Surcharge de new / delete et Memory Manager
    Bonjour � tous,

    Tout d'abord, j'ai suivi l'excellent tutoriel suivant: http://loulou.developpez.com/tutorie.../partie1/#L2.2
    Dans le tutoriel, pour ceux qui ne veulent pas lire, on apprend comment surcharger new / new[] / delete / delete[] et surtout comment traquer toutes les allocations ainsi que les d�sallocations.

    J'ai fait un code semblable, mais pourtant, moi, � la destruction du MemoryManager, il appelle mon delete surcharg�, ce qui fait que, du coup, comme memory (ma std::map) est d�truite, et que c'est elle m�me qui appelle un delete... �a crashe dans ma fonction release().

    ... Je ne comprends bien sur pas pourquoi, et j'aimerai �viter ce crash (logique). L'histoire, c'est, que comme les surcharges des op�rateurs ne sont pas visible dans le MemoryManager, pourquoi ai je cette appel � release()?

    J'attache mon code en pi�ce jointes (projet VS2010) pour que cela soit plus facile � voir que dans le forum.

    Merci pour votre aide.
    Fichiers attach�s Fichiers attach�s
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    R�ponse: Bah, le std::map fait un new que je capture avec mon memory manager lors de la destruction de ce memory manager.
    Du coup, bah �a fait tr�s mal, la moiti� des objets d�truits ... mais ... on essaie de les r�utiliser.

    Solution: J'ai r�impl�ment� une list (avec cl�s) moi m�me, utilisant les malloc() / free() pour le moment. Cela marche correctement (jusqu'� pr�sent) m�me si j'ai mis pas mal de temps � mettre en place la solution.
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  3. #3
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Citation Envoy� par LittleWhite Voir le message
    R�ponse: Bah, le std::map fait un new que je capture avec mon memory manager lors de la destruction de ce memory manager.
    Du coup, bah �a fait tr�s mal, la moiti� des objets d�truits ... mais ... on essaie de les r�utiliser.

    Solution: J'ai r�impl�ment� une list (avec cl�s) moi m�me, utilisant les malloc() / free() pour le moment. Cela marche correctement (jusqu'� pr�sent) m�me si j'ai mis pas mal de temps � mettre en place la solution.
    J'avais commenc� � regarder un peu ton code, et j'avais essay� de vider la map dans le destructeur de memorymanager. Mais le probl�me reste m�me dans ce cas. J'avoue que je n'ai pas continu� � creuser, mais cela m'a intrigu�. Reste-t-il des allocations dans la map y compris si celle ci est vide (je ne me souvient plus si j'ai essay� un std::swap(memory, temp) avec temp sur la pile.
    De plus, je n'ai pas vu de diff�rence flagrante avec la version de Laurent Gomilla et je me suis demand� s'il avait le m�me probl�me ?

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    De plus, je n'ai pas vu de diff�rence flagrante avec la version de Laurent Gomilla et je me suis demand� s'il avait le m�me probl�me ?
    J'en ai parl� directement avec Laurent Gomilla certes en MP ... ce qui n'est pas une tr�s bonne solution :s ... mais bon.
    Il n'y a pas de diff�rence dans le sens, pas de diff�rence dans l'impl�mentation (juste quelques fonctionnalit�s en plus, et des trucs (la signature) que j'ai tir� d'un bouquin sur le probl�me)
    Apr�s, mon hypoth�se (que j'avais expos� � Laurent Gomilla) �tait que lui, il avait fait le programme en 2004 / 2005 si je me rappelle bien, et que entre temps, nous pouvons avoir une impl�mentation de la std::map qui change (surtout lorsque j'utilise VS2010)
    Apr�s je peux montrer le callstack ou cela crash, mais je crois que vous avez retrac� vous aussi le probl�me.
    Apr�s, il m'a aussi conseill� que ce que je voulais faire �tait ultra dangereux, et que �a r�sultait souvent � de nombreux probl�mes (comme j'ai pu le remarquer )
    Apr�s, dans mon essai... m�me si c'�tait vide, �a plantait toujours ... � cause que semble t'il, l'impl�mentation utilise un syst�me de node ... enfin, pour le peu que j'ai compris.

    L'autre point qui ma aussi un peu perdu, c'est que malgr� le #undef de delete � la fin du main et la s�paration des impl�mentation new / delete du MemoryManager, il tente tout de m�me d'utiliser mon delete perso, et �a, il ne me semblait pas que cela devait arriver ...
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  5. #5
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Citation Envoy� par LittleWhite Voir le message
    Apr�s, mon hypoth�se (que j'avais expos� � Laurent Gomilla) �tait que lui, il avait fait le programme en 2004 / 2005 si je me rappelle bien, et que entre temps, nous pouvons avoir une impl�mentation de la std::map qui change (surtout lorsque j'utilise VS2010)
    Fortement possible.
    Citation Envoy� par LittleWhite Voir le message
    Apr�s je peux montrer le callstack ou cela crash, mais je crois que vous avez retrac� vous aussi le probl�me.
    effectivement, j'ai regard� d�j�.
    Citation Envoy� par LittleWhite Voir le message
    Apr�s, il m'a aussi conseill� que ce que je voulais faire �tait ultra dangereux, et que �a r�sultait souvent � de nombreux probl�mes (comme j'ai pu le remarquer )
    Quels sont les points risqu�s ?

    Citation Envoy� par LittleWhite Voir le message
    L'autre point qui ma aussi un peu perdu, c'est que malgr� le #undef de delete � la fin du main et la s�paration des impl�mentation new / delete du MemoryManager, il tente tout de m�me d'utiliser mon delete perso, et �a, il ne me semblait pas que cela devait arriver ...
    Je pense que cela doit venir de ces 2 d�finitions :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    inline void operator delete(void* pPointer)
    {
        MemoryManager::get().release(pPointer, false);
    }
     
    inline void operator delete[](void* pPointer)
    {
        MemoryManager::get().release(pPointer, true);
    }
    Le remplacement doit d�passer la dur�e de vie de ta variable manager ?

    et cela dans le delete :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        if ( itMemoryBlock == memory.end() )
        {
            // Can be if the pointer was not allocated with this memory manager...
    #ifdef _VERBOSE_DEBUGGING
        #ifdef _FILELOGGING
            logFile << "Memory Manager -> free (ERROR: Pointer not found in the manager)" << std::endl;
        #else
            std::cout << "Memory Manager -> free (ERROR: Pointer not found in the manager)" << std::endl;
        #endif
    #endif
            // Anyway, we have to free it
            free(pPointer);
            return;
        }
    Cela me parait tr�s bizarre (pour ne pas dire plus) de vouloir d�truire co�te que co�te un pointeur que tu ne g�res pas. D'ailleurs, si je mets en commentaire la ligne avec free, je n'ai plus d'erreur de plantage.

    En fait, j'ai l'impression que c'est rapidement un gros 'b....el' car l'utilisation de la STL et donc d'allocations/destructions implicites dans tes fonctions ... d'allocation/lib�ration peut rapidement amener � des appels r�cursifs. Peut �tre �tait-ce de cela dont Laurent voulait parler en disant que c'�tait une d�marche risqu�e ?

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    Quels sont les points risqu�s ?
    J'ai fait une boulette, mais je ne crois pas que cela avait �t� pr�cis�.
    Bien sur, le premier probl�me que l'on peut cit�, c'est celui que je rapporte ici .
    Sinon, il y a un gros risque que certaines biblioth�ques externes se fasse aussi pi�ger par le MemoryManager. L� dessus, ce ne sont que mes propres hypoth�ses (un peu na�ves)

    Le remplacement doit d�passer la dur�e de vie de ta variable manager ?
    Oui maintenant, j'en suis assez certain (et je ne dis pas cela que parce que j'ai eu le bug)
    C'est un remplacement fait au niveau du compilateur ... du coup ...

    Cela me parait tr�s bizarre (pour ne pas dire plus) de vouloir d�truire co�te que co�te un pointeur que tu ne g�res pas. D'ailleurs, si je mets en commentaire la ligne avec free, je n'ai plus d'erreur de plantage.
    Bien sur, il n'y a plus plantage. De plus, je ne veux pas d�truire ce pointeur (moi perso non)
    Mince ... je viens de comprendre le sous entendu ... vous marquez un point

    Dans le tuto de Laurent Gomilla il est dit le suivant:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // Si le bloc n'a pas été alloué, on génère une erreur
        if (It == m_Blocks.end())
        {
            // En fait ça arrive souvent, du fait que le delete surchargé
            // est pris en compte même là où on n'inclue pas DebugNew.h,
            // mais pas la macro pour le new
            // Dans ce cas on détruit le bloc et on quitte immédiatement
            free(Ptr);
            return;
        }
    Mais il est vrai ... que l'on pourrait tout simplement faire un return ...

    En fait, j'ai l'impression que c'est rapidement un gros 'b....el' car l'utilisation de la STL et donc d'allocations/destructions implicites dans tes fonctions ... d'allocation/lib�ration peut rapidement amener � des appels r�cursifs. Peut �tre �tait-ce de cela dont Laurent voulait parler en disant que c'�tait une d�marche risqu�e ?
    On peut aussi revenir sur le fait que si j'enl�ve le free() ... je fais une fuite de m�moire explicite, mais dans le code de la STL ...

    Mais mais, lorsque j'y repense ... l'erreur n'�tais pas l� ou vous le dite, chez moi ...
    elle �tait car la variable 'memory' �tait � zero.
    [edit]
    J'ai v�rifi� ... l'erreur est ici chez moi:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    // Finding the block related to this pointer
    MemoryMap::iterator itMemoryBlock = memory.find(pPointer);
    Mais sinon, oui, le fait d'enlever le free() ... enl�ve le crash O_o (je m'y perd).
    Par contre ... comme mon astucieux std::cout l'indique dans le get du singleton, le memorymanager est toujours appel� alors qu'il ne devrait pas. Ceci, j'ai r�ussi � l'�viter avec la version ou je d�fini mes propres structures de donn�es (pour remplacer la std::map)

    J'imagine que les probl�mes ne font que commencer car cela semble plus du hacking de code qu'autre chose, de vouloir faire un tel MemoryManager.
    [/edit]
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  7. #7
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Citation Envoy� par LittleWhite Voir le message
    J'ai v�rifi� ... l'erreur est ici chez moi:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    // Finding the block related to this pointer
    MemoryMap::iterator itMemoryBlock = memory.find(pPointer);
    A partir du moment o� tu lib�res un pointeur que tu n'as pas allou�, tu ne sais pas si et ce que tu as corrompu. En plus l'erreur sur le map a lieu apr�s la destruction du memory manager.
    Je pense que tu devrait avoir un new de m�me vie que ton delete, ce qui n'est pas le cas il me semble actuellement. Et je me demande si l'utilisation de la STL (string/flux) dans new/delete ne risque pas de poser des probl�mes � cause d'allocations � l'int�rieur de leur impl�mentation

  8. #8
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    Citation Envoy� par 3DArchi Voir le message
    A partir du moment o� tu lib�res un pointeur que tu n'as pas allou�, tu ne sais pas si et ce que tu as corrompu. En plus l'erreur sur le map a lieu apr�s la destruction du memory manager.
    Moi je voyais plus comme suit:
    J'ai une fonction qui est appel� pour la liberation, donc si je ne lib�re pas la m�moire, elle ne fait pas son r�le. La moiti� du temps c'est l'utilisateur qui appelle plus ou moins directement cette fonction. Si l'utilisateur passe un pointeur invalide, je dois faire comme dans un vrai programme ... et crasher (ou faire crasher le free) ... car l'utilisateur a fait une betise ...

    Je pense que tu devrait avoir un new de m�me vie que ton delete, ce qui n'est pas le cas il me semble actuellement. Et je me demande si l'utilisation de la STL (string/flux) dans new/delete ne risque pas de poser des probl�mes � cause d'allocations � l'int�rieur de leur impl�mentation
    Ce serait bien mais comment (avoir le new de m�me vie que le delete)?
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  9. #9
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Citation Envoy� par LittleWhite Voir le message
    Moi je voyais plus comme suit:
    J'ai une fonction qui est appel� pour la liberation, donc si je ne lib�re pas la m�moire, elle ne fait pas son r�le. La moiti� du temps c'est l'utilisateur qui appelle plus ou moins directement cette fonction. Si l'utilisateur passe un pointeur invalide, je dois faire comme dans un vrai programme ... et crasher (ou faire crasher le free) ... car l'utilisateur a fait une betise ...
    Mais l'adresse peut tr�s bien �tre valide mais allou�e diff�remment. A mon avis, c'est en fonction de �a :
    Ce serait bien mais comment (avoir le new de m�me vie que le delete)?
    A priori, oui. Sinon, tu risque de faire des delete qui ne correspondent pas � un new g�r� par ton memory manager.

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    Citation Envoy� par 3DArchi Voir le message
    A priori, oui. Sinon, tu risque de faire des delete qui ne correspondent pas � un new g�r� par ton memory manager.
    Euh ma question �tait du genre ... comment pourrai-je ? car l�, je manque un peu d'id�e... (m�me si vous pouviez juste m'orienter sur une solution, cela ne me g�ne pas)
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  11. #11
    R�dacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par d�faut
    Citation Envoy� par LittleWhite Voir le message
    Euh ma question �tait du genre ... comment pourrai-je ? car l�, je manque un peu d'id�e... (m�me si vous pouviez juste m'orienter sur une solution, cela ne me g�ne pas)
    Ben comme pour le delete . Tu d�finis ta propre version de l'op�rateur avec les signatures que tu veux surcharger.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    void* operator new(std::size_t size) /*throw(std::bad_alloc)*/;
    void* operator new(std::size_t size, const std::nothrow_t&) /*throw()*/;
    void operator delete(void* ptr) /*throw()*/;
    void operator delete(void* ptr, const std::nothrow_t&) throw();
    void* operator new[](std::size_t size) /*throw(std::bad_alloc)*/;
    void* operator new[](std::size_t size, const std::nothrow_t&) /*throw()*/;
    void operator delete[](void* ptr) /*throw()*/;
    void operator delete[](void* ptr, const std::nothrow_t&) /*throw()*/;
    Le probl�me va �tre l'interf�rence avec le #define new utilis� pour ajouter le fichier/ligne. J'ai pas ton code sous les yeux, mais je me demande s'il ne faut pas s�parer les surcharges des op�rateurs (new et delete) de ta macro et le fichier .h correspondant.

  12. #12
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    Merci pour votre r�ponse.

    Je viens de lire le livre: "Effective C++ Third Edition" de Scott Meyers et je dois dire que c'est un tr�s bon livre (malgr� qu'il ne couvre pas toutes mes interrogations (en m�me temps le livre qui le ferait serait �norme)

    Bref, il y a une partie (3 items) sur la surcharge des allocations de m�moire.

    D�j�, je peux dire que mon impl�mentation du new est hors norme (non conforme donc) car il manque:
    - Le cas ou on passe une taille de 0 (oui c'est une allocation valide en C++, et il faut allouer au moins 1 byte ... car elle doit renvoyer un pointeur valide)
    - La boucle qui essaie d'allouer plusieurs fois (soit avec un appel sur le callback (std::new_handler), soit lancer une exception.
    - Mon delete devrait g�r� silencieusement le cas du pointeur NULL.


    Apr�s avoir lu tout cela, je suis un peu loin d'�tre dans la bonne impl�mentation . (et on ne parle pas du thread safe, de la memory alignment et autres).

    Mais, je pensais � votre solution, de surcharger le new() global (car j'ai compris que mon code trichait, mais ne pouvait compl�tement tricher sur la partie du delete), je crois que ce serai une tr�s mauvaise id�e, car j'aurais surement un appel � new durant l'allocation de mon memory manager (donc, je reviendrai � un cas inverse de celui pour lequel je suis venu).

    Pour conclure ce message, je dois dire que la meilleure m�thode est de cr�e une classe qui r�impl�mente new et delete. Ce qui permettrait de laisser ces impl�mentations � un niveau "local". Apr�s, il faut voir les possibilit�s d'h�ritage de cette classe (h�ritage, que je voudrais garder que dans le mode DEBUG). Ou alors, une deuxi�me voix � suivre est de jouer avec des macro qui d�finissent les surcharges (mais l�..., je suis un peu moins fort sur ce poins)
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 18
    Dernier message: 07/10/2010, 02h18
  2. intrigue sur la surcharge du new et delete
    Par swirtel dans le forum C++
    R�ponses: 12
    Dernier message: 07/09/2006, 15h23
  3. [D�butant]Constructeur et new/delete
    Par Geolem dans le forum C++
    R�ponses: 5
    Dernier message: 02/12/2005, 21h11
  4. Namespace et surcharge operator new/delete
    Par ZeLegolas dans le forum C++
    R�ponses: 11
    Dernier message: 26/07/2005, 13h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo