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 d'initialisation d'une structure


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut Problème d'initialisation d'une structure
    Bonjour,

    Nous sommes en train d'essayer de réaliser une montée de version de compilateur en passant du gcc 2.96 au gcc 3.4.6.

    Lors d'un test, un traitement fonctionnel avec la compilation 2.96 produit une segmentation fault en 3.4.6.

    Après recherche, il semble que l'erreur vienne de l'initialisation d'une variable d'une structure d'erreur (la mise en commentaire de cette ligne permet au traitement de se dérouler sans soucis).

    La ligne est si basique que je ne comprends pas ce qui peut causer l'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy( StructErr->NomSource ,  NOMFIC );
    sachant que #define NOMFIC "fichierlot.c"

    La structure stockant la variable est définie dans un autre fichier comme cela:

    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
    /* structure erreur */
    typedef struct {
        short AffichageEcran;           /* Flag =OK si on affiche a l'ecran */
        char FichierLog[100];           /* Chemin du fichier log */
        char NomTache[MAXTACHE];        /* nom de la tÀche */
        int  Cr;                        /* compte-rendu */
        int  Cerr;                      /* code erreur */
        char Cemet[20+1];               /* code emetteur */
        char Cdest[20+1];               /* code destinataire */
        char NomFic[MAXNOMFICH+1];      /* nom de fichier transmis */
        char NomBord[MAXNOMFICH+1];     /* nom du bordereau */
        char NomSource[MAXNOMFICH+1];   /* nom du fichier source */
        int  Ligne;                     /* numero de ligne */
        char Comment[700];              /* commentaire */
    } T_Erreur;
    typedef T_Erreur *pT_Erreur;
    En vous remerciant par avance pour votre aide.

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut
    je ne peut pas t'aider parce ce que je connais pas le français mais peut étre ton problème vien de la ?
    struct ma_structure {
    char champ1; /* 8 bits */
    int champ2; /* 32 bits */
    char champ3; /* 8 bits */
    };
    On pourrait penser que cette structure occupera 6 octets en mémoire, et pourtant, sur une bonne partie des
    compilateurs, on obtiendrait une taille plus proche des 12 octets.
    En fait, les compilateurs insèrent quasiment toujours des octets entre les champs pour pouvoir les aligner sur des
    adresses qui correspondent à des mots machines. Cela est dû à une limitation de la plupart des processeurs, qui ne
    peuvent lire des « mots » de plus d'un octet que s'ils sont alignés sur un certain adressage (alors qu'il n'y a pas de
    contrainte particulière pour lire un seul octet, si le type char est défini sur 8bit).
    En se représentant la mémoire comme un tableau continu, on peut tracer le dessin suivant:

    | bloc N | bloc N + 1 | bloc N + 2 |
    ---+---------------+---------------+---------------+---
    | a | b | c | d | e | f | g | h | i | j | k | l |
    ---+---------------+---------------+---------------+---

    Les cases a, b, c, ... représentent des octets, et les blocs des sections de 32 bits. Si on suppose qu'une variable de type
    ma_structure doive être placée en mémoire à partir du bloc numéro N, alors un compilateur pourra, pour des raisons
    de performance, placer champ1 en a, champ2 de e à h, et champ3 en i. Cela permettrait en effet d'accéder
    simplement à champ2: le processeur fournit des instructions permettant de lire ou d'écrire directement le bloc N + 1.
    Dans ce cas, les octets de b à d ne sont pas utilisés; on dit alors que ce sont des octets de bourrage (ou padding en
    anglais). Un autre compilateur (ou le même, appelé avec des options différentes) peut aussi placer champ2 de b à e,
    et champ3 en f, pour optimiser l'utilisation mémoire. Mais alors il devra générer un code plus complexe lors des
    accès à champ2, le matériel ne lui permettant pas d'accéder en une seule instruction aux 4 octets b à e.
    En fait il faut garder à l'esprit que toutes les variables suivent cette contrainte: aussi bien les variables locales aux
    fonctions, les champs de structures, les paramètres de fonctions, etc.
    L'existence d'octets de bourrage ainsi que leur nombre sont non seulement dépendants de l'architecture, mais aussi du
    compilateur. Cela dit, il est toujours possible de connaître la « distance » (offset) d'un champ par rapport au début de
    la structure, et ce, de manière portable. Pour cela il existe une macro, déclarée dans l'entête <stddef.h>:
    j'ai copier/coller ça bonne chance

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    Merci beaucoup de ta réponse.

    Effectivement, il est possible que d'une version à l'autre du compilateur, le paddage de stockage diffère et que ce soit cela qui me pose problème. Mais du coup, je ne vois pas vraiment comment je peux régler ce problème.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Par défaut
    Salut

    je ne pense pas que ça soit un problème de pading comme suggéré par PIC16F877A étant donné que tu prends pour adresse de destination
    l'emplacement mémoire du membre NomSource, ça passera quelque soit le pading (ça ne serait pas le cas si l'offset était calculé manuellement)

    est ce qu'il ne s'agit pas d'écrasement mémoire dont ce crash est la révélation
    (StructErr est un bon pointeur ?,
    MAXNOMFICH n'est pas défini avec des valeurs différentes entre les deux fichiers ?)
    sinon peut être remplacer strcpy par strncpy , c'est plus safe mais je ne pense pas que ça résoud le cas

    Cdt

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut
    je pense que dans les paramètre de compilateur qu'il faut faire quel que chose

    par exemple dans ton compilateur définie par exemple un char = 32bits aulieu 8bits si tu as un cpu 32 et meme choses avec les autre types de variable

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 13
    Par défaut
    A priori, aucun problème avec MAXNOMFICH.

    De plus, si j'affiche NOMFIC avant. La variable est renseignée correctement et avec la bonne taille.

    J'ai testé à tout hasard strncpy () mais cela ne change rien.

    Je ne sais pas changer les paramètres de mon compilateur afin de tester la solution de stocker les char sur 32 bits au lieu de 8 bits. Aurais tu de la documentation qui pourrait me renseigner?

    Merci pour vos idées.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 59
    Par défaut
    dans strcpy(dest, src)

    le problème peux se poser avec src si ça ne se termine pas avec le '\0', pour cela strncpy est bon pour éliminer ce risque

    sinon il reste à inspecter dest , est ce qu'il découle d'une allocation mémoire valide, se trouve bien à l'intérieur de la plage occupée par StructErr (qui elle même se trouve dans la zone mémoire allée)

    le fichier où la structure est allouée et celui où elle est utilisée sont compilés avec la même version gcc, y'a t-il quelque chose qui peut faire que l'adresse/contenu de la variable à l'allocation soit différent / à l'écriture via strcpy

    Bref plein de questions auquelles le debuggeur saura mieux de répondre

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut
    Citation Envoyé par Schnouf00 Voir le message
    .

    Je ne sais pas changer les paramètres de mon compilateur afin de tester la solution de stocker les char sur 32 bits au lieu de 8 bits. Aurais tu de la documentation qui pourrait me renseigner?
    paramétres se trouve dans le ficher limits.h et voici le lien ou j'ai trouvé le texte
    http://fr.wikibooks.org/wiki/Program...s_avanc%C3%A9s peut étres
    trouver des chose qui vous aider a localiser le problème bonne chance

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

Discussions similaires

  1. initialisation d'une structure
    Par ryadh.naouar dans le forum C
    Réponses: 3
    Dernier message: 29/10/2007, 15h21
  2. Réponses: 17
    Dernier message: 09/03/2007, 18h13
  3. Problème d'initialisation d'une matrice ?
    Par wilval dans le forum C
    Réponses: 5
    Dernier message: 04/02/2007, 16h13
  4. [Linux]problème d'affectation d'une structure
    Par cimcim dans le forum Linux
    Réponses: 5
    Dernier message: 11/12/2006, 17h13
  5. [Initialisation] Remplir une structure une fois
    Par Kimael dans le forum Langage
    Réponses: 14
    Dernier message: 08/06/2004, 15h33

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