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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 100
    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 100
    Billets dans le blog
    146
    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 100
    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 100
    Billets dans le blog
    146
    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 100
    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 100
    Billets dans le blog
    146
    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 100
    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 100
    Billets dans le blog
    146
    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.

+ 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