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 :

Run-Time Check Failure : Stack corrupted


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut Run-Time Check Failure : Stack corrupted
    Bonjour,

    voilà, j'ai un ptit souci avec mon appli que je suis en train de développer en C++, sous visual studio 2003.

    ça compile bien,
    mais en cours d'exécution, à un moment,
    j'ai une erreur :
    Run-Time Check Failure #2 - Stack around the variable 'mess' was corrupted
    Je vois à peu près d'où, ça vient
    mais je sais pas trop comment le résoudre...

    Voilà comment ça se présente :

    j'ai une structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct Message {
        int longueur;
        char *data;
        }
    j'ai une variable statique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static vector<Message> fileAttente;
    et voici ce que je fais dans une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Message mess;
     
    CreerMessage(&mess);    // appel à une méthode qui me permet d'élaborer mon message
     
    // je place mon message dans la file d'attente...
    fileAttente.push_back(mess);
     
    // j'envoie le message...
    EnvoyerMessage();
    Ma méthode 'EnvoyerMessage' se charge d'envoyer les messages qui sont dans la file d'attente
    elle les supprime de la file d'attente une fois qu'ils sont envoyés...

    Voici donc, je pense le point du problème...

    Donc comment je dois m'y prendre pour faire ça correctement??...

    Merci

  2. #2
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    Run-Time Check Failure #2 - Stack around the variable 'mess' was corrupted
    ca arrive quand?
    dans cette methode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fileAttente.push_back(mess);
    ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Non,

    en fait, tout ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Message mess;
     
    CreerMessage(&mess);    // appel à une méthode qui me permet d'élaborer mon message
     
    // je place mon message dans la file d'attente...
    fileAttente.push_back(mess);
     
    // j'envoie le message...
    EnvoyerMessage();
    est dans une même méthode
    et c'est en sortant de cette méthode que l'erreur tombe...

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Peut être que la pile est corrompue parce que quelqu'un jardine en dehors de ses plate bandes.

    Que fait le constructeur de mess, que fait la fonction CreerMessage(), que fait le constructeur de copie de Message, que fait la fonction EnvoyerMessage()
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Est-ce que tu pourrais nous montrer plus de code, comme la définition complète de la struct Message, CreerMessage() et EnvoyerMessage() ?

    Personellement, je commencerais pas modifier la struct Message en la remplacant par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct Message
    { 
       std::vector<char> data; // si c'est ce n'est pas du texte
       // ou 
       std::string data; // si c'est du texte.
    };
    justement, pour m'épargner ce genre d'ennui.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Il n'y a pas de constructeur pour Message

    La méthode CreerMessage affecte une valeur aux champs de la structure...
    Et EnvoyerMessage envoie les messages qui sont dans la file d'attente et les supprime ensuite de la liste (avec un fileAttente.erase )
    je pense que c'est le fait de supprimer le message de la file d'attente qui fait péter l'erreur
    nan?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Bonjour,
    Est-ce que tu pourrais nous montrer plus de code, comme la définition complète de la struct Message, CreerMessage() et EnvoyerMessage() ?

    Personellement, je commencerais pas modifier la struct Message en la remplacant par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct Message
    { 
       std::vector<char> data; // si c'est ce n'est pas du texte
       // ou 
       std::string data; // si c'est du texte.
    };
    justement, pour m'épargner ce genre d'ennui.
    La struct message est complète

    Et justement, j'ai besoin d'un 'char *'
    car le message est destiné à une librairie en C qui attend du char*

  8. #8
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    Et justement, j'ai besoin d'un 'char *'

    ca te donne un const char*

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Ouais mais ça m'aide pas pour la constitution de mon message (dans CreerMessage) car en fait, il s'agit d'un tableau d'octets...

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    peux tu poster
    CreerMessage() et EnvoyerMessage() ?

  11. #11
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Citation Envoyé par melleb Voir le message
    La struct message est complète
    C'est un peu ce que je craignais
    Il faudrait voir CreerMessage() et EnvoyerMessage() pour débusquer l'erreur, mais elle est probablement dans une mauvaise utilisation du char* data.

    Si c'est possible, std::vector<char> est réellement la solution la plus simple pour faire un buffer d'octet. La librairie C qui attends un char* peut toujours recevoir &vec[0].

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Bah, c'est à dire que c'est un peu chaud
    mon code utilise tout plein de structure, donc pas terrible pour la compréhension...

    j'vais voir avec le std::vector<char> et le &vec[0]...

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Bon, je galère toujours,
    j'vous mets donc un aperçu de mes méthodes...

    Mais j'vous préviens, hein,
    c'est pas super beau
    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
    struct Message {
    	mot longueur;
    	octet *data;
    } ;
     
    struct t_msg_dmde_abnt_sp
    {
      octet nature;
      char  nom_dmdeur [MAX_NOM_DMDEUR];
      mot   periode;
      octet horodat;
      octet attrib_upc;
      mot   nb_upc;      
      octet data;
    } ;

    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
    void MaMethode()
    {
    	Message messAbnt;
    	t_msg_dmde_abnt_sp	mess;
     
    	// Création du message 
    	hr = CreerMessage(&messAbnt.longueur,
    				   &mess);
     
    	messAbnt.data = (octet*)&mess;
     
    	fileAttente.push_back(messAbnt);
     
    	TraiterEnvoiMessages();
    }
    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
    HRESULT CreerMessage(mot *longueurMessage,
    			t_msg_dmde_abnt_sp *messAbnt)
    {
    	HRESULT				hr = S_OK;
    	wstring				chaine;
    	mot					lgDataRP = 0;
    	t_ent_table_def_sp	def_upc;
    	octet				*dataUPC;
    	int i;
     
    	USES_CONVERSION;
     
    	/* Calcul de la taille du message */
    	/**********************************/
    	//...
    	*longueurMessage = (mot)(sizeof(struct1) + lgDataRP);
     
    	messAbnt->data = (octet)malloc (sizeof(struct2) + lgDataRP);
     
    	/* Elaboration du message */
    	/**************************/
    	messAbnt->nature = ...;
    	StringCbCopy(messAbnt->nom_dmdeur, MAX_NOM_DMDEUR, APPLICATION_ID);
     
    	messAbnt->periode = ...;
    	messAbnt->horodat = ...;
    	messAbnt->attrib_upc = ...;	// mode Normal uniquement
    	messAbnt->nb_upc = ...;
     
     
    	dataUPC = new octet[sizeof(struct2) + lgDataRP];
    	for (int i = 0; j < sizeof(struct2) + lgDataRP; i++)
    	{
    		//...
    		dataUPC[i] = ...;
    	}
     
    	memcpy ( &messAbnt->data, dataUPC, sizeof(struct2) + lgDataRP); 
     
    	delete(dataUPC);
    	return hr;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void TraiterEnvoiMessages()
    {
    	// ... en boucle ...
    	// envoi du 1er message de la liste d'attente
    	// puis suppression du message qui vient d'être envoyé
    	fileAttente.erase(fileAttente.begin());
    }
    J'avais aussi un souci au passage du paramètre 'longueurMessage' dans la méthode CreerMessage...
    ça me retournait un truc pas cohérent, pas ce qui était affecté dans la méthode
    J'ai réussi à le résoudre en passant par une variable intermédiaire (plutôt que de passer '&messAbnt.longueur')


    Vous pouvez m'aider à présent pour le pile corrompue???

  14. #14
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    et si tu tentes ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    HRESULT CreerMessage(mot &longueurMessage,
    			t_msg_dmde_abnt_sp &messAbnt)
    {

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void MaMethode()
    {
    	Message messAbnt;
    	t_msg_dmde_abnt_sp	mess;
     
    	// Création du message 
    	hr = CreerMessage(messAbnt.longueur,   mess);

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    ça ne change rien

    j'ai toujours l'erreur "Stack around the variable 'mess' was corrupted" en sortant de MaMethode...


    Mais, en fait, c'est quoi la différence entre ce que j'avais fait et ce que tu m'as proposé??

  16. #16
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    loicounet, pointeur ou référence en argument, ce n'est pas ça qui peut corrompre la pile quand même...

    Le problème des pile corrompue, c'est que les symptomes peuvent être très variés. Ca peut venir d'un débordement de tableau, d'un memset pas où il faut, d'un pointeur qui se ballade un peu trop loin etc.

    Melleb, est ce que tu pourrais créer un exemple minimal qui compile et qui reproduit le bug ? Par exemple en mettant tous les trucs comme periode, horodat, attrib_upc à zéro, et en virant tout le superflu. On pourrait essayer de débugger de notre coté...

    Il y des petits trucs bizarre dans le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0; j < sizeof(struct2) + lgDataRP; i++)
    Le j au milieu c 'est une erreur en recopiant ?
    wstring ça correspond à quoi ? std::wstring ou un typedef sur autre chose ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    messAbnt->data = (octet)malloc (sizeof(struct2) + lgDataRP);
    Quand est-ce que messAbnt->data est libéré ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    StringCbCopy(messAbnt->nom_dmdeur, MAX_NOM_DMDEUR, APPLICATION_ID);
    C'est quoi APPLICATION_ID ici ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    messAbnt->data = (octet)malloc (sizeof(struct2) + lgDataRP);
    Ce n'est pas plutot (octet*) ?

  17. #17
    Membre éprouvé
    Inscrit en
    Avril 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 155
    Par défaut
    loicounet, pointeur ou référence en argument, ce n'est pas ça qui peut corrompre la pile quand même...
    -->la methode attend un pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    HRESULT CreerMessage(mot *longueurMessage,
    			t_msg_dmde_abnt_sp *messAbnt)
    et le code lui donne une reference:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    hr = CreerMessage(&messAbnt.longueur,
    				   &mess);
    sous un cast on ne sait pas trop ce qui se passe réellement, une erreur d'exécution peut provenir d'un cast mal utilisé des fois!
    c'est pour ca que je suggérais de tout mettre en référence afin d'éviter les cast implicites...

  18. #18
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Melleb, est ce que tu pourrais créer un exemple minimal qui compile et qui reproduit le bug ? Par exemple en mettant tous les trucs comme periode, horodat, attrib_upc à zéro, et en virant tout le superflu. On pourrait essayer de débugger de notre coté...
    Bah comme vous avez pu vous en apercevoir,
    mon appli est assez complexe
    elle s'interface sur des librairies C...

    Citation Envoyé par Arzar Voir le message
    Il y des petits trucs bizarre dans le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for (int i = 0; j < sizeof(struct2) + lgDataRP; i++)
    Le j au milieu c 'est une erreur en recopiant ?
    Oui, évidemment, c'est une erreur...

    Citation Envoyé par Arzar Voir le message
    wstring ça correspond à quoi ? std::wstring ou un typedef sur autre chose ?
    c'est bien du std::wstring

    Citation Envoyé par Arzar Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    messAbnt->data = (octet)malloc (sizeof(struct2) + lgDataRP);
    Quand est-ce que messAbnt->data est libéré ?
    c'est libéré au moment où le message est retiré de la file d'attente...

    Citation Envoyé par Arzar Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    StringCbCopy(messAbnt->nom_dmdeur, MAX_NOM_DMDEUR, APPLICATION_ID);
    C'est quoi APPLICATION_ID ici ?
    c'est un truc du genre const char[]

    Citation Envoyé par Arzar Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    messAbnt->data = (octet)malloc (sizeof(struct2) + lgDataRP);
    Ce n'est pas plutot (octet*) ?
    non justement


    pppfff trop galère

  19. #19
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    c'est libéré au moment où le message est retiré de la file d'attente...
    Dans TraiterEnvoiMessages() ?
    fileAttente.erase(fileAttente.begin()); ne libère rien du tout en tout cas.

    > Ce n'est pas plutot (octet*) ?
    non justement
    malloc renvoit une addresse (un void*), a priori ça n'a aucun sens de la caster en octet (donc en unsigned char, une valeur entre 0 et 255)


    Edit : Un truc qui peut peut être t'aider, on ne sait jamais...

    Si la struct Message ne comporte que des types natifs (float, int) et des tableaux (char[MAX_LENGTH]) et surtout pas de pointeur (char*) alors la struct est dite POD (Plain old data), et dans ce cas la struct est obligatoirement contigue en mémoire, donc on peut la passer directement à une fonction C, du style func(char* buffer, int length).

    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
     
    struct Message
    {
       Message():
       nature(0),
       periode(0),
       horodat(0),
       attrib_upc(0),
       nb_upc(0),
       data(0)
       {
       }
     
      octet nature;
      char  nom_dmdeur [MAX_NOM_DMDEUR];
      mot   periode;
      octet horodat;
      octet attrib_upc;
      mot   nb_upc;      
      octet data;
    } ;
     
    fonctionC(char* buffer, int longueur);
     
    int main()
    {
       Message m;
      // remplir m
      // ...
     
      fonctionC((char*)&m, sizeof(m);
    }

  20. #20
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Par défaut
    Citation Envoyé par Arzar Voir le message
    malloc renvoit une addresse (un void*), a priori ça n'a aucun sens de la caster en octet (donc en unsigned char, une valeur entre 0 et 255)
    En fait, je crois que le champ 'data' de la structure sert à sauvegarder l'adresse où se trouve le tableau d'octet...


    Citation Envoyé par Arzar Voir le message
    Edit : Un truc qui peut peut être t'aider, on ne sait jamais...

    Si la struct Message ne comporte que des types natifs (float, int) et des tableaux (char[MAX_LENGTH]) et surtout pas de pointeur (char*) alors la struct est dite POD (Plain old data), et dans ce cas la struct est obligatoirement contigue en mémoire, donc on peut la passer directement à une fonction C, du style func(char* buffer, int length).

    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
     
    struct Message
    {
       Message():
       nature(0),
       periode(0),
       horodat(0),
       attrib_upc(0),
       nb_upc(0),
       data(0)
       {
       }
     
      octet nature;
      char  nom_dmdeur [MAX_NOM_DMDEUR];
      mot   periode;
      octet horodat;
      octet attrib_upc;
      mot   nb_upc;      
      octet data;
    } ;
     
    fonctionC(char* buffer, int longueur);
     
    int main()
    {
       Message m;
      // remplir m
      // ...
     
      fonctionC((char*)&m, sizeof(m);
    }
    oui, c'est ce qui je fait je crois...

Discussions similaires

  1. Réponses: 1
    Dernier message: 08/02/2009, 11h54
  2. Stack corrupted - Run-Time Check Failure
    Par poukill dans le forum C++
    Réponses: 2
    Dernier message: 16/07/2008, 23h31
  3. probleme avec C++ Run-Time Check Failure #3
    Par acnalbasac dans le forum C++
    Réponses: 3
    Dernier message: 14/04/2007, 14h57
  4. [VC++2005 express]Run-Time Check Failure #2
    Par méphistopheles dans le forum Visual C++
    Réponses: 3
    Dernier message: 19/01/2007, 07h13
  5. Run-Time Check Failure #2
    Par -Mod- dans le forum DirectX
    Réponses: 5
    Dernier message: 10/08/2006, 08h06

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