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 :

Problème avec une structure


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 92
    Points
    92
    Par défaut Problème avec une structure
    Bonjours à tous,

    Je m'essaye en ce moment à la lecture des fichiers au format intel Hex (.hex produits par les compilateurs pour microcontroleur, par exemple) et je rencontre quelques problèmes. Je m'en remets donc à vos expériences.

    Dans mon programme ,je définis une structure puis un pointeur du type de cette structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct {
        unsigned char *donnees;     // Pointeur sur les données contenu dans le fichier
        unsigned long *erreurs;     // Pointeur sur les n° de ligne ayant une erreur
        unsigned long errs_chksum;  // Nombre d'erreurs contenues dans le champ précédent
    }HEX;
     
    typedef HEX *pHEX; 	// Pointeur de type HEX
    Au tout début de ce programme, je déclare le pointeur "hex" de type pHEX que j'alloue via un malloc et que je passe en argument à la fonction qui pose problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    pHEX hex;
    hex = (pHEX)malloc(sizeof(HEX));
     
    lire_hex("D:\\Documents and Settings\\Administrateur\\Mes documents\\prog\\intel\\main.hex",
                 hex);
    Cette fonction a pour but de lire un fichier .hex en entier et remplir la structure comme suit:
    - le champ donnees reçoit les données contenues dans le fichier
    - le champ erreurs reçoit les numéros de ligne où il y a des erreurs de checksum
    - le champ errs_chksum reçoit le nombre d'erreur de checksum

    Je vous mets les parties de la fonction lire_hex qui posent problème :

    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
    void lire_hex(char chemin[512], pHEX fich){
        FILE *fichier;
        int exist = 0;
     
        n = 0;
        fich->errs_chksum = 0;
     
        if((fichier = fopen(chemin,"rb")) == NULL) printf("Erreur d'ouverture du fichier\n");
        else{
            do{
               ......
     
                   if(!exist){
                       if( ( fich->donnees = (unsigned char *)malloc(sizeof(unsigned char) * nb) ) == NULL)
                            printf("Erreur de malloc pour fich->donnees");
                       exist = 1;
                   }
                   else if((fich->donnees = (unsigned char *)realloc(fich->donnees, sizeof(unsigned char) * nb)) == NULL)
                        printf("Erreur de realloc de fich->donnees");
    		........
                   }
               else verrou = 1;
           }while(!verrou);
           fclose(fichier);
      }
    }
    Le programme s'exécute mais n'affiche rien (pourtant ma fonction d'affichage fonctionne) et retourne une valeur d'erreur incompréhensible, du coup je passe en debug. Là, au premier tour de la boucle tout se passe bien mais au second tour à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    else if((fich->donnees = (unsigned char *)realloc(fich->donnees, sizeof(unsigned char) * nb)) == NULL)
                        printf("Erreur de realloc de fich->donnees");
    le debugger retourne une erreur de :

    Program received signal SIGTRAP, Trace/breakpoint trap.
    In _libmsvcrt_a_iname () ()
    Je ne comprends pas pourquoi j'ai cette erreur. Y a-t-il une erreur dans mon code ? ou est-ce un bug dû à mes outils de dev ?
    Je travaille sous CodeBlocks avec Mingw et gdb. Je suis pas un gourou en C donc j'utilise peut-être mal l'allocation de mémoire à une structure.

    Désolé d'être aussi long et merci pour l'aide que vous pourrez m'apporter.

    Titux
    “La folie, c’est se comporter de la même manière et s’attendre à un résultat différent.” Albert E.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Salut, pour l'utilisation de realloc, regarde ici http://emmanuel-delahaye.developpez....es.htm#realloc

    sinon au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pHEX hex;
    hex = (pHEX)malloc(sizeof(HEX));
    fait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pHEX hex=malloc(sizeof(*hex));
    après tous les malloc, teste si ton pointeur est NULL !!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if(hex==NULL)
    {
     fprintf(stderr,"Erreur\n");
     exit(EXIT_FAILURE);
    }
    je ne sais pas si ça va bcp t'aider, mais essaye de déjà modifier tout ça.

  3. #3
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 92
    Points
    92
    Par défaut
    merci pour ta réponse salseropom j'avais oublié de tester cette allocation alors que je le fais partout ailleurs. je vais ajouter ça à mon code.

    pour ce qui est de realloc, je pense savoir l'utiliser mais je postais pour voir s'il n'y avait pas de bug dans ce que j'ai écrit, en fait ce matin j'ai trouvé qu'en ajoutant un printf à la fin de ma boucle le prog s'exécute parfaitement. Du coup je me demande si ce serait pas CodeBlocks qui débloque vu que sous netbeans ca marche.

    à+

    Titux
    “La folie, c’est se comporter de la même manière et s’attendre à un résultat différent.” Albert E.

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par titux
    ..j'ai trouvé qu'en ajoutant un printf à la fin de ma boucle le prog s'exécute parfaitement.
    ..
    Du coup je me demande si ce serait pas CodeBlocks qui débloque vu que sous netbeans ca marche.
    Comportement typique de dépassement de mémoire...

    Et il y a 99.99% de chances que ce soit ton prog par rapport à des outils testés et re-testés..

    Dans le code que tu as fournit, comment est défini nb (non déclaré) ? et n ? à quoi sert-il ?

    D'autre part, fais-tu bien le même traitement d'allocations pour erreurs que tu fais pour donnees ??
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  5. #5
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 92
    Points
    92
    Par défaut
    Tu avais vu juste souviron34, nb et n étaient déclarés en int donc il devait en effet y avoir un dépassement de mémoire sur n.
    Mais c'est étonnant car mon fichier .hex avec lequel je teste mon prog comporte 10 lignes avec 16 octets de données par ligne.

    n recevait le nombre d'octets de données, donc 16 avec le fichier testé.
    nb recevait le nombre total d'octets stockés dans le champ "donnees" de la structure, ici 160.

    Vu que ces valeurs sont inférieures à 255 je trouve étonnant d'avoir un dépassement de mémoire mais bon, j'ai déclaré n et nb en long et c'est passé.

    Du coup, comme ca passait j'ai voulu tester un nouveau truc mais je ne me souviens plus quoi. Ca n'a pas marché donc j'ai enlevé ce que j'avais ajouté et j'ai de nouveau le même problème : en debug je reçoit un SIGTRAP toujours sur le realloc de donnees et je dois encore ajouter un printf mais au début du prog cette fois.
    Pour tenter de résoudre ça j'ai déclaré un max de variables en long en ne laissant en int que ce qui me sert de booléen.
    C'est peut-être pas non plus très bon de tout déclarer en long (?).

    Sinon pour erreurs je fais exactement le même traitement : un pointeur auquel j'alloue de la mémoire et que je redimensionne après. Cette partie là fonctionne, avec 10 lignes en tout cas.

    Là je craque ça fait quelques semaines que je suis dessus, mon code me paraît bon même si c'est folklorique pour un informaticien, à la base je suis un électronicien qui débute en prog pc... Donc je pose le code (220 lignes) et le fichier .hex de test, si une bonne âme a le courage de se pencher dessus... je l'en remercie d'avance.

    En tout cas merci souviron34 tu m'as bien aidé.

    Titux
    Fichiers attachés Fichiers attachés
    “La folie, c’est se comporter de la même manière et s’attendre à un résultat différent.” Albert E.

  6. #6
    Membre régulier
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 92
    Points
    92
    Par défaut
    J'ai un semblant de piste :
    hier j'ai été aidé pour le debug par un programmeur amateur mais d'un meilleur niveau que le mien.

    En bref et d'après lui, excepté une ligne douteuse, il n'y aurait pas de problème de mémoire dans mon code. Jusque là j'ai travaillé ce programme sous windows, hier on l'a testé sous linux et il s'exécute entièrement et ne produit apparement pas d'erreur.

    Sous windows j'utilise cygwin où gcc est présent en version 3.4.4-3 alors que la version linux est la 4.1.2. Donc peut être que cette ligne douteuse passe moins bien avec le gcc de cygwin qu'avec le gcc de linux.

    La ligne douteuse est la suivante, ligne 123 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    else fich->donnees[fich->nb_donnees] = ((ligne[i]& 0x0F)<<4 | (ligne[i+1]& 0x0F));
    fich->donnees étant alloué via un malloc il serait risqué ou incorrect d'y accéder de cette façon.

    Est-il possible que cette ligne pose problème à un ancienne version de gcc ? (peu probable, je pense)
    Est-ce une bonne façon d'affecter un élément d'un tableau dynamique ?

    Titux
    “La folie, c’est se comporter de la même manière et s’attendre à un résultat différent.” Albert E.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. problème avec une structure en C
    Par anthony.pa dans le forum C
    Réponses: 2
    Dernier message: 12/02/2013, 14h51
  2. Problème std::set avec une structure
    Par DeathMixer dans le forum C++
    Réponses: 4
    Dernier message: 03/10/2009, 01h05
  3. Problème avec une structure
    Par pegase.90 dans le forum C
    Réponses: 2
    Dernier message: 04/12/2007, 17h34
  4. Problème avec une structure
    Par Pierre.g dans le forum C
    Réponses: 4
    Dernier message: 30/12/2006, 12h22
  5. Probléme avec une structure
    Par astragoth dans le forum C++
    Réponses: 3
    Dernier message: 25/04/2006, 20h31

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