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 :

comportement d'affectation bizarre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de Ardeciel
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 28
    Par défaut comportement d'affectation bizarre
    bonjour !

    je suis en train de manipuler des listes et des piles. Voici les strucutres correspondante :

    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
     
    typedef struct
    {
            char* nomElt; //nom de l'élément
            TYPE typeElt; //nom du type de l'elt
            union
            {
                    int val_INT;
                    boolean val_BOOL;
                    char val_CHAR;
            };//valeur  de l'elt ; un de ces trois champs sera renseigne selon le type de l'elt
            struct stListSymbole * next; //chainage vers le suivant dans la liste
    } stListSymbole;
     
    //structure definissant la pile des tables des symboles
    //les operations "depiler" et "empiler" sont effectuees par les fonctions "creerTds" //et "supprimeTds"
    struct stPileTableSymbole {
     
            int nbTables; //le nombre de table dans la pile
            struct stEltPile *tableActive; //le sommet de la pile
    };
     
    //structure definissant un element de la pile
    struct stEltPile {
     
            struct stEltPile* suivant;//la table suivante (en dessous) dans la pile
            stListSymbole *table;//l'element de la pile en lui meme repesente par sa tete de liste
    };
     
    void initPileTable(); //initialise la pile de table des symboles lors de la toute //premiere utilisation
    struct stPileTableSymbole pileTable; //la pile en elle meme
     
    stListSymbole* ajoutSymbole (char * nom); //ajoute un symbole dans la table //active ; renvoie un pointeur sur la nouvelle tete de liste
                                                            //ou NULL en cas d'echec.
    stListSymbole* existeSymbole (stListSymbole *liste, char * ident); //parcours la //table des symboles passee en parametre et 
                                                    //si un elt de nom "ident" s'y trouve deja renvoie un //pointeur decu, NULL sinon.
    voici le code qui me donne du fil a retordre :

    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
     
    stListSymbole * ajoutSymbole(char * nom)
    {
            printf("1) dans ajout symb-> ancienne tête = %s\n",(pileTable.tableActive)->table->nomElt);
            stListSymbole * ptrNewElt;
            ptrNewElt = (stListSymbole *) malloc(sizeof(stListSymbole));
            if(ptrNewElt == NULL)
                    return NULL;
     
            memset(ptrNewElt,0,sizeof(stListSymbole));
     
            printf("2) dans ajout symb-> ancienne tête = %s\n",(pileTable.tableActive)->table->nomElt);
     
            ptrNewElt->nomElt = strdup(nom);
            ptrNewElt->typeElt = INT;
     
            printf("3) dans ajout symb-> ancienne tête = %s\n",(pileTable.tableActive)->table->nomElt);
     
            ptrNewElt->next = (struct stListSymbole*)(pileTable.tableActive)->table;//on chaine le nouvel elt au reste de la liste 
            (pileTable.tableActive)->table = ptrNewElt; //on met a jour la tete de liste sur le nouvel elt
     
            printf("dans ajout symb-> nouv tête = %s\n",(pileTable.tableActive)->table->nomElt);
            printf("dans ajour symbole ->précédent = %s\n",((stListSymbole*)ptrNewElt->next)->nomElt);
            return ptrNewElt;
    }
    ce qui se passe c'est qu'au 1) et 2), j'ai (pileTable.tableActive)->table->nomElt qui est à null, ce qui est normal.
    mais au 3), il devient égale à "nom" ! alors que je n'ai pas encore chainé ptrNewElt à (pileTable.tableActive)->table !
    je ne comprend pas ce comportement, pouvez vous m'aider ?

    Ardeciel

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ben, déjà, je ne comprends pas trop l'utilité du cast dans la partie 3...

    (de plus, on ne caste pas le retour de malloc() en C et les unions anonymes ne sont pas standard (du moins, pas en C90)). Sans compter que dans les paramètres des fonctions, nom devrait être de type const char *
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti Avatar de Ardeciel
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 28
    Par défaut
    je viens de faire les modifications que tu préconises... ça change rien du tout.
    le cast dans la partie 3 sert à ne pas avoir un :

    attention : assignment from incompatible pointer type

    à la compilation.

    Ardeciel

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Es-tu sûr que tu as vraiment besoin du cast, ou n'as-tu pas plutôt besoin de changer le code autour ?
    Le type a-t-il une bonne raison d'être incorrect ?

    (voir la citation de ma signature).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti Avatar de Ardeciel
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 28
    Par défaut
    si tu regardes les définitions de mes structure , tu devrais voir que "next" est une "struct stListSymbole *" et que "table" est un "stListSymbole *", c'est à cause de ça que je doit faire un cast, mêmes si je ne comprends pas bien pourquoi.

    ensuite, je ne pense pas que ce cast explique pourquoi une variable (pileTable.tableActive->table) est affectée par un strdup sur une tout autre variable ( ptrNewElt) qui n'est acunement chainée à ce moment là.

    Ardeciel

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par Ardeciel Voir le message
    si tu regardes les définitions de mes structure , tu devrais voir que "next" est une "struct stListSymbole *" et que "table" est un "stListSymbole *", c'est à cause de ça que je doit faire un cast, mêmes si je ne comprends pas bien pourquoi.
    Parce que le type struct stListSymbole * n'existe pas: Ta structure est anonyme.

    ensuite, je ne pense pas que ce cast explique pourquoi une variable (pileTable.tableActive->table) est affectée par un strdup sur une tout autre variable ( ptrNewElt) qui n'est acunement chainée à ce moment là.
    Parce que j'ai du mal à comprendre ton code, et qu'affecter un pointeur du mauvais type est toujours une mauvaise idée, donc la cause la plus probable tant qu'elle n'est pas prouvée fausse.

    Mais en effet, j'avais mal compris la question et le code litigieux intervient après les symptomes, donc passons.
    Je ne vois pas d'explication à ton erreur, à moins que tu n'aies fait un "mauvais free()" avant.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti Avatar de Ardeciel
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 28
    Par défaut
    premier élément de réponse :
    ptrNewElt et piletalble.tableActive->table ont la même adresse, ce qui explique pourquoi le strdup affecte les deux.

    Maintenant : pourquoi ces deux variable ont-elles la même adresse ?
    je demande une nouvelle zone mémoire avec le malloc, je ne comprend pas pourquoi il utilise celle là !

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

Discussions similaires

  1. Comportement de String bizarre
    Par ram-0000 dans le forum Android
    Réponses: 6
    Dernier message: 18/04/2012, 18h04
  2. comportement boucle for bizarre
    Par maccormick dans le forum Général Java
    Réponses: 9
    Dernier message: 22/09/2010, 14h07
  3. comportement CSS ultra bizarre
    Par saimonesays dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 27/03/2010, 21h22
  4. Comportement d'impression bizarre
    Par Mad Ant dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 22/03/2007, 09h40
  5. Comportement des affectations en java
    Par DemonKN dans le forum Langage
    Réponses: 2
    Dernier message: 09/10/2006, 12h00

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