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 :

surdefinition operateur new et delete


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut surdefinition operateur new et delete
    Bonjour à tous
    Comme mon titre l'indique je souhaite effectuer une surdefinition des operateurs new/delete afin de pouvoir logger les eventuelles fuites de memoires. Mon travail se base sur le 1er tutorial du moteur 3d Yes::Engine de Laurent Gomila (1000 Mercis pour ce super tutorial).
    Donc dans mon travail j'utilise les surdefinitions ecrites dans le Yes::Engine ainsi que le meme "MemoryManager".
    Tout fonctionne tres bien jusqu'à l'utilisation d'un delete... seg fault...
    exemple d'un programme tout simple mais qui ne fonctionne pas avec le log des allocations/liberations memoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #define _DEBUG
    #include "DebugNew.h"
     
     
    int main(int argc, char **argv)
    {
        int i =0; //variable bidon
        i++;      //code bidon
     
        int *test = new int(); //reservation memoire
     
        i++;     //code bidon
        i = 5;  //code bidon
     
        *test = 5 + i;  
     
        delete test;    //liberation
    }
    Voila donc le code ci dessus ne fonctionne pas. En mode pas à pas il plante sur le new... (Le log du "memory manager" est vide)
    Etrangement si j'enleve le "delete test;" le code fonctionne Mais bien sur fuite de memoire... (elle est meme logguée dans le rapport des fuites).
    Bien sur le code fonctionne si j'enleve #define _DEBUG

    J'utilise Dev cpp 4.9.9.2 avec gcc 3.4.2

    Donc si quelqu'un aurait une piste je suis preneur merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    De toutes manières, je suis personnellement pas fan du tout de ce truc.
    Déjà pour deboguer je préfère utiliser des outils faits pour ça qui de toutes façons seront bien plus puissants que des opérateurs surchargés et en plus ce truc fait l'allocation avec malloc, a priori moins performant que l'allocateur de base.

    Enfin bref Laurent devrait passer, il te dira sûrement où se situe le problème.

  3. #3
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    J'avais eu le même problème, de mémoire il faut instancier le MemoryManager une première fois (via un appelle à la méthode Instance, me semble que c'est un singleton) avant de commencer à allouer quoi que ce soit.

  4. #4
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Ca compile bien chez moi.

    As-tu fais des manipulations particulières avec les classes du tutorial ?

    Ou est-ce que tu réutilise mot pour mot les fichiers de surcharge d'opérateur, de Singleton, de Memorymanager et de CFile ?

    Si tu as fais des copier/coller dans ton unique fichier DebugNew.h, as tu bien fait attention de où tu plaçais tes macros ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    Tout d'abord merci pour vos réponses.

    J'avais eu le même problème, de mémoire il faut instancier le MemoryManager une première fois (via un appelle à la méthode Instance, me semble que c'est un singleton) avant de commencer à allouer quoi que ce soit.
    Oui en effet MemoryManager est un singleton. Appeler la methode instance() avant ne change rien a mon probleme

    Ca compile bien chez moi.
    As-tu fais des manipulations particulières avec les classes du tutorial ?
    Ou est-ce que tu réutilise mot pour mot les fichiers de surcharge d'opérateur, de Singleton, de Memorymanager et de CFile ?
    Si tu as fais des copier/coller dans ton unique fichier DebugNew.h, as tu bien fait attention de où tu plaçais tes macros ?
    Au debut j'ai essayé de creer ma propre surdef. et memory manager mais sans succes. Du coup jai ecris ce petit programe test en utilisant exactement les sources du yes::Engine (DebugNew.h, File.h/.cpp, MemoryManager.h/.cpp) La classe n'est pas construite a partir de CSingleton.

  6. #6
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Citation Envoyé par johjoh
    La classe n'est pas construite a partir de CSingleton.
    En effet, désolé pour la confusion.

    Citation Envoyé par johjoh
    Du coup jai ecris ce petit programe test en utilisant exactement les sources du yes::Engine (DebugNew.h, File.h/.cpp, MemoryManager.h/.cpp)
    Je suppose que tu as supprime tous les YES_EXPORT et tous les #include export.h ?

    Par ailleurs, tu ne devrait pas définir le _DEBUG dans ton main.cpp, mais bien dans tes directives de compilations, car actuellement il n'est pas définit au moment où tu compile par exemple MemoryManager.cpp et File.cpp

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    oui en effet j'ai bien supprimé les YES_EXPORT... et le export.h
    et pour ce qui est de la directive du compilateur, je viens de tester à l'instant mais sans succes
    Ce que je trouve bizarre, c'est le fait que le programme "marche" si je ne fais pas de delete et que si j'en fais un il plante sur le new (seg fault) alors que je n'ai rien modifié (juste commenter le delete), logiquement si mon delete était incorrect ca devrait planter sur mon delete non?

  8. #8
    Membre chevronné
    Inscrit en
    Novembre 2006
    Messages
    362
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 362
    Par défaut
    Je n'ai pas plus d'idée que ça. En tout cas, cela compile ici.

    Dans le doute, essaie de tout régénérer, ton compilo s'est peut-être emmellé les pinceaux.

    sinon, tu peux toujours poster le code exact des fichiers issus du tutorial que tu utilises... Au cas où ça aide à trouver le problème.

    On est bien d'accord : tu ne linke pas avec la dll générée à partir du tutorial ?

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    on s'est peut etre mal compris, moi aussi cela compile tres bien
    c'est l'execution le probleme :S
    Nonon je ne link pas avec la dll...
    Voici le code complet utilisé :

    mon main.cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    #include "DebugNew.h"
     
    int main(int argc, char **argv)
    {
        int i =0;
        i++;
     
        int *test = new int();
        i++;
        i = 5;
        delete test;    
     
        return 0;
    }
    mon debugnew.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    //==========================================================
    // DebugNew.h
    //
    // Surcharge des opérateurs / fonctions d'allocation et de
    // désallocation de la mémoire pour traquer les fuites
    //
    //==========================================================
     
    #ifdef _DEBUG
     
    #ifndef DEBUGNEW_H
    #define DEBUGNEW_H
     
    //==========================================================
    // En-têtes
    //==========================================================
    #include "MemoryManager.h"
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur new
    //
    // [in] Size : Taille à allouer
    // [in] File : Fichier source
    // [in] Line : Ligne dans le fichier source
    //
    // [retval] Pointeur sur la zone allouée
    //
    ////////////////////////////////////////////////////////////
    inline void* operator new(std::size_t Size, const char* File, int Line)
    {
        return Yes::CMemoryManager::Instance().Allocate(Size, File, Line, false);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur new[]
    //
    // [in] Size : Taille à allouer
    // [in] File : Fichier source
    // [in] Line : Ligne dans le fichier source
    //
    // [retval] Pointeur sur la zone allouée
    //
    ////////////////////////////////////////////////////////////
    inline void* operator new[](std::size_t Size, const char* File, int Line)
    {
        return Yes::CMemoryManager::Instance().Allocate(Size, File, Line, true);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur delete
    //
    // [in] Ptr : Pointeur sur la zone à libérer
    //
    ////////////////////////////////////////////////////////////
    inline void operator delete(void* Ptr)
    {
        Yes::CMemoryManager::Instance().Free(Ptr, false);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur delete
    //
    // [in] Ptr :  Pointeur sur la zone à libérer
    // [in] File : Fichier source
    // [in] Line : Ligne dans le fichier source
    //
    ////////////////////////////////////////////////////////////
    inline void operator delete(void* Ptr, const char* File, int Line)
    {
        Yes::CMemoryManager::Instance().NextDelete(File, Line);
        Yes::CMemoryManager::Instance().Free(Ptr, false);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur delete[]
    //
    // [in] Ptr : Pointeur sur la zone à libérer
    //
    ////////////////////////////////////////////////////////////
    inline void operator delete[](void* Ptr)
    {
        Yes::CMemoryManager::Instance().Free(Ptr, true);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Surcharge de l'opérateur delete[]
    //
    // [in] Ptr :  Pointeur sur la zone à libérer
    // [in] File : Fichier source
    // [in] Line : Ligne dans le fichier source
    //
    ////////////////////////////////////////////////////////////
    inline void operator delete[](void* Ptr, const char* File, int Line)
    {
        Yes::CMemoryManager::Instance().NextDelete(File, Line);
        Yes::CMemoryManager::Instance().Free(Ptr, true);
    }
     
    #endif // DEBUGNEW_H
     
     
    //==========================================================
    // Définition de macros servant à automatiser le tracking
    // /!\ sortir des directives anti-réinclusions !
    //==========================================================
    #ifndef new
        #define new    new(__FILE__, __LINE__)
        #define delete Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__), delete
    #endif
     
    #endif // _DEBUG
    mon MemoryManager.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    //==========================================================
    // MemoryManager.h
    //
    // Définition de la classe CMemoryManager
    //
    //==========================================================
     
    #ifndef MEMORYMANAGER_H
    #define MEMORYMANAGER_H
     
    //==========================================================
    // En-têtes
    //==========================================================
    #include "File.h"
    #include <fstream>
    #include <map>
    #include <stack>
    #include <string>
     
     
    namespace Yes
    {
        //==========================================================
        // Gestionnaire de mémoire - détecte les fuites
        //==========================================================
        class  CMemoryManager
        {
        public :
     
            //----------------------------------------------------------
            // Renvoie l'instance de la classe
            //----------------------------------------------------------
            static CMemoryManager& Instance();
     
            //----------------------------------------------------------
            // Ajoute une allocation mémoire
            //----------------------------------------------------------
            void* Allocate(std::size_t Size, const CFile& File, int Line, bool Array);
     
            //----------------------------------------------------------
            // Retire une allocation mémoire
            //----------------------------------------------------------
            void Free(void* Ptr, bool Array);
     
            //----------------------------------------------------------
            // Sauvegarde les infos sur la désallocation courante
            //----------------------------------------------------------
            void NextDelete(const CFile& File, int Line);
     
        private :
     
            //----------------------------------------------------------
            // Constructeur par défaut
            //----------------------------------------------------------
            CMemoryManager();
     
            //----------------------------------------------------------
            // Destructeur
            //----------------------------------------------------------
            ~CMemoryManager();
     
            //----------------------------------------------------------
            // Inscrit le rapport sur les fuites de mémoire
            //----------------------------------------------------------
            void ReportLeaks();
     
            //----------------------------------------------------------
            // Types
            //----------------------------------------------------------
            struct TBlock
            {
                std::size_t Size;  // Taille allouée
                CFile       File;  // Fichier contenant l'allocation
                int         Line;  // Ligne de l'allocation
                bool        Array; // Est-ce un objet ou un tableau ?
            };
            typedef std::map<void*, TBlock> TBlockMap;
     
            //----------------------------------------------------------
            // Données membres
            //----------------------------------------------------------
            std::ofstream      m_File;        // Fichier de sortie
            TBlockMap          m_Blocks;      // Blocs de mémoire alloués
            std::stack<TBlock> m_DeleteStack; // Pile dont le sommet contient la ligne et le fichier de la prochaine désallocation
        };
     
    } // namespace Yes
     
    #endif // MEMORYMANAGER_H
    mon MemoryManager.cpp (ici les exceptions ont ete desactive)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    //==========================================================
    // MemoryManager.cpp
    //
    // Implantation de la classe CMemoryManager
    //
    //==========================================================
     
     
    //==========================================================
    // En-têtes
    //==========================================================
    #include "MemoryManager.h"
    #include <iomanip>
    #include <sstream>
     
     
    namespace Yes
    {
     
    ////////////////////////////////////////////////////////////
    // Constructeur par défaut
    //
    ////////////////////////////////////////////////////////////
    CMemoryManager::CMemoryManager() :
    m_File("Memory leaks.log")
    {
        // On vérifie que le fichier est bien ouvert
        if (!m_File)
            return;//throw CLoadingFailed("Memory leaks.log", "Impossible d'accéder en écriture");
     
        // Inscription de l'en-tête du fichier
        m_File << "  ========================================" << std::endl;
        m_File << "   Yes::Engine v0.1 - Memory leak tracker " << std::endl;
        m_File << "  ========================================" << std::endl << std::endl;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Destructeur
    //
    ////////////////////////////////////////////////////////////
    CMemoryManager::~CMemoryManager()
    {
        if (m_Blocks.empty())
        {
            // Aucune fuite, bravo !
            m_File << std::endl;
            m_File << "  ========================================" << std::endl;
            m_File << "     No leak detected, congratulations !  " << std::endl;
            m_File << "  ========================================" << std::endl;
        }
        else
        {
            // Fuites mémoires =(
            m_File << std::endl;
            m_File << "  ========================================" << std::endl;
            m_File << "   Oops... Some leaks have been detected  " << std::endl;
            m_File << "  ========================================" << std::endl;
            m_File << std::endl;
     
            ReportLeaks();
        }
    }
     
     
    ////////////////////////////////////////////////////////////
    // Renvoie l'instance de la classe
    //
    // [retval] Référence sur l'instance unique de la classe
    //
    ////////////////////////////////////////////////////////////
    CMemoryManager& CMemoryManager::Instance()
    {
        static CMemoryManager Inst;
     
        return Inst;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Inscrit le rapport sur les fuites de mémoire
    //
    ////////////////////////////////////////////////////////////
    void CMemoryManager::ReportLeaks()
    {
        // Détail des fuites
        std::size_t TotalSize = 0;
        for (TBlockMap::iterator i = m_Blocks.begin(); i != m_Blocks.end(); ++i)
        {
            // Ajout de la taille du bloc au cumul
            TotalSize += i->second.Size;
     
            // Inscription dans le fichier des informations sur le bloc courant
            m_File << "-> 0x" << i->first
                   << " | "   << std::setw(7) << std::setfill(' ') << static_cast<int>(i->second.Size) << " octets"
                   << " | "   << i->second.File.Filename() << " (" << i->second.Line << ")" << std::endl;
     
            // Libération de la mémoire
            free(i->first);
        }
     
        // Affichage du cumul des fuites
        m_File << std::endl << std::endl << "-- "
               << static_cast<int>(m_Blocks.size()) << " blocs non-libéré(s), "
               << static_cast<int>(TotalSize)       << " octets --"
               << std::endl;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Ajoute une allocation mémoire
    //
    // [in] Size :  Taille allouée
    // [in] File :  Fichier contenant l'allocation
    // [in] Line :  Ligne de l'allocation
    // [in] Array : True si c'est une allocation de tableau
    //
    // [retval] Pointeur sur la mémoire allouée
    //
    ////////////////////////////////////////////////////////////
    void* CMemoryManager::Allocate(std::size_t Size, const CFile& File, int Line, bool Array)
    {
        // Allocation de la mémoire
        void* Ptr = malloc(Size);
     
        // Ajout du bloc à la liste des blocs alloués
        TBlock NewBlock;
        NewBlock.Size  = Size;
        NewBlock.File  = File;
        NewBlock.Line  = Line;
        NewBlock.Array = Array;
        m_Blocks[Ptr]  = NewBlock;
     
        // Loggization
        m_File << "++ Allocation    | 0x" << Ptr
               << " | " << std::setw(7) << std::setfill(' ') << static_cast<int>(NewBlock.Size) << " octets"
               << " | " << NewBlock.File.Filename() << " (" << NewBlock.Line << ")" << std::endl;
     
        return Ptr;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Retire une allocation mémoire
    //
    // [in] Ptr :   Adresse de la mémoire desallouée
    // [in] Array : True si c'est une désallocation de tableau
    //
    ////////////////////////////////////////////////////////////
    void CMemoryManager::Free(void* Ptr, bool Array)
    {
        // Recherche de l'adresse dans les blocs alloués
        TBlockMap::iterator It = m_Blocks.find(Ptr);
     
        // 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;
        }
     
        // Si le type d'allocation ne correspond pas, on génère une erreur
        if (It->second.Array != Array)
        {
            return;//throw CBadDelete(Ptr, It->second.File.Filename(), It->second.Line, !Array);
        }
     
        // Finalement, si tout va bien, on supprime le bloc et on loggiz tout ça
        m_File << "-- Désallocation | 0x" << Ptr
               << " | " << std::setw(7) << std::setfill(' ') << static_cast<int>(It->second.Size) << " octets"
               << " | " << m_DeleteStack.top().File.Filename() << " (" << m_DeleteStack.top().Line << ")" << std::endl;
        m_Blocks.erase(It);
        m_DeleteStack.pop();
     
        // Libération de la mémoire
        free(Ptr);
    }
     
     
    ////////////////////////////////////////////////////////////
    // Sauvegarde les infos sur la désallocation en cours
    //
    // [in] File :  Fichier contenant la désallocation
    // [in] Line :  Ligne de la désallocation
    //
    ////////////////////////////////////////////////////////////
    void CMemoryManager::NextDelete(const CFile& File, int Line)
    {
        TBlock Delete;
        Delete.File = File;
        Delete.Line = Line;
     
        m_DeleteStack.push(Delete);
    }
     
    } // namespace Yes
    et mon file.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    //==========================================================
    // File.h
    //
    // Définition de la classe CFile
    //
    //==========================================================
     
    #ifndef FILE_H
    #define FILE_H
     
    //==========================================================
    // En-têtes
    //==========================================================
    #include <string>
     
     
    namespace Yes
    {
        //==========================================================
        // Classe facilitant la manipulation des fichiers
        //==========================================================
        class  CFile
        {
        public :
     
            //----------------------------------------------------------
            // Constructeur à partir d'un std::string
            //----------------------------------------------------------
            CFile(const std::string& Name = "unknown");
     
            //----------------------------------------------------------
            // Constructeur à partir d'un const char*
            //----------------------------------------------------------
            CFile(const char* Name);
     
            //----------------------------------------------------------
            // Indique si le fichier existe ou non
            //----------------------------------------------------------
            bool Exists() const;
     
            //----------------------------------------------------------
            // Renvoie le nom du fichier avec son chemin complet
            //----------------------------------------------------------
            const std::string& Fullname() const;
     
            //----------------------------------------------------------
            // Renvoie le nom du fichier sans son chemin
            //----------------------------------------------------------
            std::string Filename() const;
     
            //----------------------------------------------------------
            // Renvoie le nom du fichier sans extension ni chemin
            //----------------------------------------------------------
            std::string ShortFilename() const;
     
            //----------------------------------------------------------
            // Renvoie l'extension du fichier
            //----------------------------------------------------------
            std::string Extension() const;
     
        private :
     
            //----------------------------------------------------------
            // Données membres
            //----------------------------------------------------------
            std::string m_Name; // Chemin complet du fichier
        };
     
    } // namespace Yes
     
     
    #endif // FILE_H
    mon file.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    //==========================================================
    // File.cpp
    //
    // Implantation de la classe CFile
    //
    //==========================================================
     
     
    //==========================================================
    // En-têtes
    //==========================================================
    #include "File.h"
    #include <algorithm>
    #include <fstream>
     
     
    namespace Yes
    {
     
    ////////////////////////////////////////////////////////////
    // Constructeur à partir d'un std::string
    //
    // [in] sName : Chemin complet du fichier
    //
    ////////////////////////////////////////////////////////////
    CFile::CFile(const std::string& Name) :
    m_Name(Name)
    {
        std::replace(m_Name.begin(), m_Name.end(), '/', '\\');
    }
     
     
    ////////////////////////////////////////////////////////////
    // Constructeur à partir d'un const char*
    //
    // [in] sName : Chemin complet du fichier
    //
    ////////////////////////////////////////////////////////////
    CFile::CFile(const char* Name) :
    m_Name(Name)
    {
        std::replace(m_Name.begin(), m_Name.end(), '/', '\\');
    }
     
     
    ////////////////////////////////////////////////////////////
    // Indique si le fichier existe ou non
    //
    // [retval] True si le fichier existe
    //
    ////////////////////////////////////////////////////////////
    bool CFile::Exists() const
    {
    	std::ifstream File(m_Name.c_str());
     
        return File.is_open();
    }
     
     
    ////////////////////////////////////////////////////////////
    // Renvoie le nom du fichier avec son chemin complet
    //
    // [retval] Chemin complet du fichier
    //
    ////////////////////////////////////////////////////////////
    const std::string& CFile::Fullname() const
    {
        return m_Name;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Renvoie le nom du fichier sans son chemin
    //
    // [retval] Nom du fichier
    //
    ////////////////////////////////////////////////////////////
    std::string CFile::Filename() const
    {
        std::string::size_type Pos = m_Name.find_last_of("\\/");
     
        if (Pos != std::string::npos)
            return m_Name.substr(Pos + 1, std::string::npos);
        else
            return m_Name;
    }
     
     
    ////////////////////////////////////////////////////////////
    // Renvoie le nom du fichier sans extension ni chemin
    //
    // [retval] Nom du fichier
    //
    ////////////////////////////////////////////////////////////
    std::string CFile::ShortFilename() const
    {
        return Filename().substr(0, Filename().find_last_of("."));
    }
     
     
    ////////////////////////////////////////////////////////////
    // Renvoie l'extension du fichier
    //
    // [retval] Extension du fichier
    //
    ////////////////////////////////////////////////////////////
    std::string CFile::Extension() const
    {
        std::string::size_type Pos = m_Name.find_last_of(".");
        if (Pos != std::string::npos)
            return m_Name.substr(Pos + 1, std::string::npos);
        else
            return "";
    }
     
    } // namespace Yes

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    Donc a force de debuggage je viens de trouver plus precisement l'endroit du probleme.
    Le probleme survient pendant le new (uniquement lorsqu'il y a un delete apres) donc le new execute bien la fonction new surdefinie et le plantage survient à l'appelle de Yes::CMemoryManager::Instance().Allocate(Size, File, Line, false), le programme ne rentre meme pas dans la fonction et cet appelle provoque une seg fault... alors que s'il n'y a pas de delete l'appelle de cette fonction marche ...
    A ne rien y comprende

    Edit : il semblerai que le fonction MemoryManager::Instance() soit appelee en boucle jusqu'a plantage du programme.

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 125
    Par défaut
    Je viens de compiler ton programme avec cygwin et avec codebloc
    et j ai pas eu de pb, le fichier de leak est bien créé.

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 125
    Par défaut
    apres tests

    j ai des pb de comprehension sur la macro delete néanmoins quand je la met en commentaire je plante, ce qui est logique car le new de ton memory manager fait un malloc et donc le delete n'est pas remplace par le Free

    tu devrais tester dans un premier temps sans passer par les macros
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__);
    Yes::CMemoryManager::Instance().Free(test, false);

  13. #13
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Par défaut
    Bonjour,

    et en essayant à la place de
    *test = 5 + i;

    *test = ( 5 + i ) ;

    salut.

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    Je viens de compiler ton programme avec cygwin et avec codebloc
    et j ai pas eu de pb, le fichier de leak est bien créé.
    interessant, quelle compilateur utilises tu avec codebloc? le fichier leak creé n'est pas vide? (il devrait normalement y avoir ttes les reservations de memoire meme s'il n'y a pas de fuite et si il y a fuite un listing de celle ci. Dans tout les cas si le fichier leak est vide c'est que ça plante)


    apres tests

    j ai des pb de comprehension sur la macro delete néanmoins quand je la met en commentaire je plante, ce qui est logique car le new de ton memory manager fait un malloc et donc le delete n'est pas remplace par le Free

    tu devrais tester dans un premier temps sans passer par les macros
    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__); 
     
    Yes::CMemoryManager::Instance().Free(test, false);
    Tres interessant tout ça, cela fonctionne parfaitement si j'utilise ces 2 lignes.
    De plus si je mets en commentaire la maccro delete comme tu le dis, j'ai la meme erreur que si elle n'est pas en commentaire.
    conclusion la maccro delete a un petit soucis!!!
    Je regarderais tout ça plus profondement demain
    merci a tous pour votre aide, je sens qu'on approche du but

  15. #15
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Citation Envoyé par johjoh
    Donc a force de debuggage je viens de trouver plus precisement l'endroit du probleme.
    Le probleme survient pendant le new (uniquement lorsqu'il y a un delete apres) donc le new execute bien la fonction new surdefinie et le plantage survient à l'appelle de Yes::CMemoryManager::Instance().Allocate(Size, File, Line, false), le programme ne rentre meme pas dans la fonction et cet appelle provoque une seg fault... alors que s'il n'y a pas de delete l'appelle de cette fonction marche ...
    A ne rien y comprende

    Edit : il semblerai que le fonction MemoryManager::Instance() soit appelee en boucle jusqu'a plantage du programme.
    C'est exactement le problème que j'avais. Lorsque tu as essayé d'instancier le MemoryManager une première fois, est-ce que le fichier redéfinissant le new et le delete était inclus dans le fichier faisant cet appel ? Si c'est le cas c'est normal que cela n'a pas marché, pour résoudre ce problème j'avais appelé MemoryManager::Instance() depuis un endroit du code ou DebugNew.h n'était pas inclus (il ne faut pas non plus qu'il soit inclus dans une header lui-même inclus dans le fichier faisant ce premier appel). Un truc du genre :

    fichier main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    #include prog.h
     
    int main(int argc, char* argv) {
        MemoryManager::Instance();
        startProg();
    }
    fichier prog.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //Ne pas inclure DebugNew ici
    void startProg();
    fichier prog.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #include DebugNew.h
     
    void statrProg() {
    //implémentation
    La raison est que lors de la création du MemoryManager, un delete est appelé à un moment dans le code de la STL. Or ce delete a justement été redéfini par tes soins, et appelle MemoryManager::Instance, qui crée alors un MemoryManager puisque le premier n'est pas entièrement construit, etc etc ...

    Le seul truc que je ne comprends pas, c'et pouruqoi si le programme ne contient pas de delete, lors de l'instanciation de MemoryManager le delete appelé n'est pas celui redéfini mais celui de base.

    Bref j'espère que cela résoudra ton problème, j'ai ressorti mon code et c'est bien comme ça que je l'ai résolu, sinon je sais plus quoi faire

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    Arf j'ai cru que ca marchais mais non en faites, j'avais oublier de definir _DEBUG...
    exactement meme probleme

  17. #17
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Content que ça aie marché

    Pense au tag

    Maintenant manque plus que la raison de l'appel au delete redéfini lorsqu'un appel à delete est présent dans la suite du code, et un appel au delete non redéfini dans le cas contraire. Tu utilises quel compilo ?

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    en faites desolé mais ca n'a pas marché.... j'ai edité mon post apres :S

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 24
    Par défaut
    donc d'autres pistes que j'ai trouver a force de chercher.
    Je me suis dis, je vais supprimer la maccro et faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__);
    delete(test);
    puisque ce qui suit fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__);  
    Yes::CMemoryManager::Instance().Free(test, false); //code de la fonction surdefinie de l'operateur delete
    et la non ca ne fonctionne pas.
    A force de recherche, j'ai remarquer que la fonction de l'operateur delete surdefinie est appelé plus d'une dizaine de fois!! alors que si je supprime mon seule et unique delete elle n'est pas appelée du tout...

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 125
    Par défaut
    ton pb semble venir du precompilateur,

    as tu fait un include de debugnew dans ton memorymanager.c et h ?

    sinon modifie la macro delete dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     #define delete2 Yes::CMemoryManager::Instance().NextDelete(__FILE__, __LINE__), delete
    et fait l'appel avec delete2

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Redéfinition opérateurs new et delete globaux
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 30/07/2007, 11h34
  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. Operateur "new" renvoi NULL
    Par Demerzel_01 dans le forum C++
    Réponses: 25
    Dernier message: 07/07/2006, 09h43
  4. Allocation Dynamique de Memoire Avec Operateur New
    Par msstaf dans le forum C++Builder
    Réponses: 3
    Dernier message: 30/06/2006, 15h49
  5. Segmentation fault sur new[] et delete[]
    Par Don ViP dans le forum C++
    Réponses: 4
    Dernier message: 30/04/2006, 00h29

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