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 :

Memory corruption : comment déboguer ?


Sujet :

C++

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut Memory corruption : comment déboguer ?
    Bonjour,

    J'ai une DLL qui a besoin d'allouer un tableau d'entier, dont le nombre d'élément est variable selon les cas.

    Lorsque ça tente d'allouer un tableau de 0 ou 1 entier, ça crash :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Windows has triggered a breakpoint in myApp.exe.
     
    This may be due to a corruption of the heap, which indicates a bug in myApp.exe or any of the DLLs it has loaded.
     
    This may also be due to the user pressing F12 while myApp.exe has focus.
     
    The output window may have more diagnostic information.
    En revanche, pour 2 ou plus, ça ne crash pas..

    Qu'est-ce que je peux faire pour gérer ça ?

    Merci
    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    quel est le code en question de l'allocation ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    De ce genre là :

    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
     
    struct DataSet
    {
    	DataSet();
    	~DataSet();
     
    	void Reserve(int iCount);
    	int AddData(void* pUserData);
     
    	SUserData* m_pData;
    	int m_iCount;
    	int m_iCapacity;
    	int m_iBuffer;
    	void* m_pCaps[10];
    };
     
    struct Context
    {
        DataSet mSets[7];
    };
     
    struct ADataType
    {
       ADataType();
       ~ADataType();
       int* m_Tab;
    };
     
    // Dans un .cpp :
    ADataType::ADataType()
    {
       int iCount = Config.GetCount();
       m_Tab = new int[iCount ];
    }
     
    ADataType::~ADataType()
    {
       delete[] m_Tab;
    }
    Dans un .h, je définis la valeur par défaut d'un "ADataType" ainsi :
    const ADataType ADataTypeDefault = ADataType();

    Lorsque ma DLL se charge, le "Config.GetCount()" renvoie 0, et ça fonctionne.

    Plus tard, lorsque j'initialise mes données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Context myContext;
    myContext.mSets[0].m_pCaps[1] = new ADataType[1];
    Et c'est là que ça crash, le new ADataType[1] appelle le constructeur de ADataType, et lorsque la valeur de Config.GetCount() est de 0 ou 1, supérieure à 1, ça ne crash pas.

    Y a-t-il quelque chose de bizarre dans ce code ?

    Merci
    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    A priori oui, il y a des trucs qui me paraissent bizarre

    Pourquoi un void* ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ADataType** m_pCaps[10];
    Faire un new avec une taille de 0, ça crashera toujours, il faut gérer cette valeur particulière.
    Une valeur de 1 ne devrait pas entraîner de crash. Es-tu sûr qu'il s'agit de 1 et non 0 ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    La valeur de zéro ne provoque pas de crash dans le cas où ça initialise la DLL :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    const ADataType ADataTypeDefault = ADataType();
    Et oui je suis sûr que la valeur 1 crash.

    Par ailleurs, j'ai juste mis ceci :
    Avec en dure "1" dans le constructeur :
    Et ça crash quand même
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  6. #6
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Citation Envoyé par mister3957 Voir le message
    Par ailleurs, j'ai juste mis ceci :
    Avec en dure "1" dans le constructeur :
    Et ça crash quand même
    Du coup la fonction Config.GetCount() fait quoi ? (est-elle toujours appelée ?)
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Du coup la fonction Config.GetCount() fait quoi ? (est-elle toujours appelée ?)
    Config.GetCount() n'est plus appelé.

    En fait, j'ai réduit le scope du problème, et :

    - La DLL réceptionne un pointeur void*, du style "UserData", l'enregistre et renvoie un identifiant.
    - L'exécutable envoie ses données à la DLL, et gère les identifiants.

    Pour gérer les identifiants, il me fallait un conteneur à la fois capable de retrouver la donnée via l'identifiant, que l'identifiant via la donnée. Ainsi, j'ai utilisé le multi_index_container.

    Je me suis rendu compte que selon la volumétrie passée à ce conteneur, ça crachait à différents endroits (dans une instruction côté EXE comme DLL).

    Au lieu d'utiliser ça, j'ai changer mon implémentation en utilisant deux map, et là ça fonctionne très bien. Donc je pense que c'est soit le multi_index_container qui déconne, soit l'utilisation que j'en fais.

    Dans ce multi_index_container, j'utilise trois index (sequentiel, par identifiant, par données). Avec une version de boost, ça crachait sauf si je ne laissais que l'index séquentiel (toujours des problèmes de mémoire), et avec une autre version, c'est le problème ci dessus.

    Alors je suis en train de recompiler une version de boost, la dernière, et si ça se reproduit, je ferai un autre sujet, spécifique à ce conteneur.

    En tout cas merci pour votre écoute

    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

Discussions similaires

  1. Comment déboguer avec W32DAsm ou OllyDbg
    Par Amiraamir dans le forum x86 32-bits / 64-bits
    Réponses: 5
    Dernier message: 26/06/2009, 11h52
  2. Réponses: 0
    Dernier message: 18/09/2007, 19h07
  3. memory corruption
    Par GLSpirit dans le forum C++
    Réponses: 2
    Dernier message: 23/05/2007, 08h42
  4. comment déboguer son code ?
    Par AdHoc dans le forum Zend
    Réponses: 11
    Dernier message: 05/02/2007, 15h03
  5. Comment déboguer une DLL??
    Par Mickey.jet dans le forum EDI
    Réponses: 5
    Dernier message: 30/03/2006, 08h50

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