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 :

Pointeur sur char* déplacé par incrémentation d'une autre variable


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Pointeur sur char* déplacé par incrémentation d'une autre variable
    Bonjour à tous,

    Bonne année 2010 !!
    J'ai un drôle de problème qui me pertube beaucoup, si vous pouviez m'aider j'en serais ravi !
    L'idée générale : mettre des chaines de caractères dans une liste chaînée. Pour chaque élément de la liste, je copie une chaine de caractère en plusieurs morceaux dedans. Puis j'incrémente un compteur pour avoir le nombre total d'éléments dans ma liste. Sauf que l'incrémentation de ce compteur déplace le pointeur sur la chaine de caractère qui se trouve dans le premier élément de la liste !

    Quelques détails :
    - une structure de type sl_i contient un pointeur sur le début de la liste, un autre sur la fin de la liste, et le fameux compteur.
    - la liste chaînée est composée d'une structure de type s_node nommée new. Elle est remplie dans la fonction lb_fill_node, où tout se passe très bien.

    Mon problème :
    - avant la ligne "i_sl->len = i_sl->len + 1", tout va très bien. Quand je tape sous gdb "p i_sl->bg->name", j'obtiens bien "REMOTEHOST".
    - après cette ligne, "p i_sl->bg->name" donne "EMOTEHOST".
    - quand j'insère d'autres éléments (avec une fonction construite sur le même modèle), j'obtiens "MOTEHOST", et ainsi de suite, jusqu'à avoir une chaîne vide.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    sl_i            *ins_first_elem(sl_i *i_sl, char *environ)
    {
      s_node        *new;
     
      new = xmalloc(sizeof(s_node), "ins_first_elem");
      new = lb_fill_node(environ, new);
      new->next = NULL;
      i_sl->bg = new;
      i_sl->end = new;
      i_sl->len = i_sl->len + 1;
      return (i_sl);
    }
    Mes deux structures :
    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
     
    typedef struct  s_node
    {
      char          *name;
      int           len1;
      char          *arg;
      int           len2;
      struct s_node *next;
    } s_node;
     
    typedef struct  sl_i
    {
      s_node        *bg;
      s_node        *end;
      int           len;
    } sl_i;
    En vous remerciant,
    Nathan
    Dernière modification par Melem ; 10/01/2010 à 17h26.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 632
    Points
    23 632
    Par défaut
    Citation Envoyé par feydaykyn Voir le message
    Mon problème :
    - avant la ligne "i_sl->len = i_sl->len + 1", tout va très bien. Quand je tape sous gdb "p i_sl->bg->name", j'obtiens bien "REMOTEHOST".
    - après cette ligne, "p i_sl->bg->name" donne "EMOTEHOST".
    - quand j'insère d'autres éléments (avec une fonction construite sur le même modèle), j'obtiens "MOTEHOST", et ainsi de suite, jusqu'à avoir une chaîne vide.
    Es-tu sûr de ne pas avoir écrit union à la place de struct ?

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      new = xmalloc(sizeof(s_node), "ins_first_elem");
      new = lb_fill_node(environ, new);
      new->next = NULL;
      return (i_sl);
    }
    Remarque : return est un mot-clé, pas une fonction. Les parenthèses sont inutiles.

    Il nous faudrait le code de tes deux autres fonctions. En particulier, es-tu certain de ce que renvoit lb_fill_node() ? Ça m'étonne que tu aies besoin de réaffecter new.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour Obsidian,

    merci de m'aider !

    J'ai bien écrit "struct" hélas
    Mon école nous impose une norme de codage, d'où les parenthèses autour de return.

    J'ai commenté le compteur, et tout fonctionne parfaitement, mais je ne comprends pas vraiment pourquoi...

    Voici la fonction lb_fill_node. Je pense comme toi que la ré-affectation est inutile en théorie, mais en pratique j'ai déjà eu des cas où elle était nécessaire malgré la théorie, du coup je force la ré-affectation le temps de corriger tous les bugs de mon programme puis je l'enlève ensuite.

    Cette fonction découpe une chaîne qui est sous la forme "PWD=/usr/desktop"
    en deux chaînes, name qui contient le nom, et arg qui contient la variable. J'en profite pour stocker la longueur de chaque chaîne au passage.
    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
     
    s_node          *lb_fill_node(char *environ, s_node *new)
    {
      int           j;
      int           k;
     
      j = 0;
      k = 0;
      new->len1 = my_strlen_symb(environ, '=') + 1;
      new->name = xmalloc(new->len1 * sizeof(char *), "envi_to_ll");
      while (environ[j] != '=')
        {
          new->name[j] = environ[j];
          j++;
        }
      new->name[j] = '\0';
      new->len2 = my_strlen_symb(&environ[++j], '\0') + 1;
      new->arg = xmalloc(new->len2 * sizeof(char *), "envi_to_ll");
      while (environ[j] != '\0')
        {
          new->arg[k] = environ[j];
          k++;
          j++;
        }
      new->arg[k] = '\0';
      return (new);
    }
    Et la fonction qui met dans la liste chaînée :
    "s_node *current" reçoit "i_sl->end".

    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
     
    sl_i            *ins_end_list(sl_i *i_sl, s_node *current, char *environ)
    {
      s_node        *new_end;
     
      if (current == NULL)
        return (ins_first_elem(i_sl, environ));
      new_end = xmalloc(sizeof(s_node), "ins_end_list");
      new_end = lb_fill_node(environ, new_end);
      current->next = new_end;
      new_end->next = NULL;
      i_sl->end = new_end;
      /*  i_sl->len++;*/
      return (i_sl);
    }
    Merci encore !!

  4. #4
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Code feydaykyn : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    new->name = xmalloc(new->len1 * sizeof(char *), "envi_to_ll");
    new->arg = xmalloc(new->len2 * sizeof(char *), "envi_to_ll");
    Pourquoi char * ?
    Code feydaykyn : Sélectionner tout - Visualiser dans une fenêtre à part
    new_end = lb_fill_node(environ, new_end);
    En effet l'affectation est inutile, tu pourrais profiter du retour de la fonction pour la gestion d'erreur d'allocation, au niveau de tes xmalloc
    To start press any key. (reading screen) Where's the "any" key? I see Esc, Catarl, and Pig Up. There doesn't seem to be any "any" key. Wo! All this computer hacking is making me thirsty. I think I'll order a Tab. (presses TAB key). -- HOMER --

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    "char *", parce que je trouve que c'est plus clair que "*(new->name)" Par ailleurs, mes xmalloc font un exit(EXIT_FAILURE), donc pas besoin d'un retour de fonction particulier. Ce n'est pas très élégant, et je pense que je ferai quelque chose de plus propre par la suite, qui libèrerait la mémoire allouée jusqu'à l'erreur du malloc avant de quitter (d'ailleurs je pense que je posterai sur ce sujet, parce qu'il y a quelque chose que je ne sais pas comment implémenter. Eh oui encore du boulot pour vous !).

    L'affectation est bien inutile, je la vire dès que j'ai résolu mon problème promis !

    Merci encore et bonne soirée,
    Nathan

  6. #6
    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 Obsidian Voir le message
    Remarque : return est un mot-clé, pas une fonction. Les parenthèses sont inutiles.
    dans ce cas-là

    Mais ce serait à préciser, à mon avis...

    Là ta remarque est valable parce qui n'y a qu'une seule valeur, sans calcul(s)..


    Les parenthèses sont utiles (au moins pour la lisibilité) si l'on faisait :

    Et même pire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int fct (void)
    {
      double a, b, c ;
     
    ..
     
    return a + 3*b + c ;
    }
    "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

  7. #7
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Citation Envoyé par feydaykyn Voir le message
    Bonsoir,

    "char *", parce que je trouve que c'est plus clair que "*(new->name)" ...
    Nathan
    Tes xmalloc c'est pour allouer des chaînes de caractères non ? dans se cas c'est sizeof( char ) qu'il faut mettre. ( sachant que sizeof(char)==1 tu pourrais ne pas la mettre aussi )
    To start press any key. (reading screen) Where's the "any" key? I see Esc, Catarl, and Pig Up. There doesn't seem to be any "any" key. Wo! All this computer hacking is making me thirsty. I think I'll order a Tab. (presses TAB key). -- HOMER --

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 632
    Points
    23 632
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Là ta remarque est valable parce qui n'y a qu'une seule valeur, sans calcul(s).. Les parenthèses sont utiles (au moins pour la lisibilité) si l'on faisait :
    Peut-être bien, mais cela est vrai d'une manière générale et n'est aucunement lié à return. Je pensais que c'était implicite dans mes propos.

  9. #9
    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
    lol implicite est bien le maître-mot

    Mais au vu du PO et de ses posts, je pense que dans ce cas l'explicite est mieux ..

    Mais bon, c'était en passant ..
    "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

  10. #10
    Invité
    Invité(e)
    Par défaut
    @ssmario2 : je te dois une fière chandelle, grâce à ta remarque tout est soudain rentré dans l'ordre !! Merci beaucoup vraiment !

    @souviron34 : qu'est-ce qu'un "PO" ?

    Merci à tous pour votre temps :-)
    Nathan

  11. #11
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    qu'est-ce qu'un "PO" ?
    Le posteur à l'origine de la discussion, c'est à dire toi.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

Discussions similaires

  1. passage par pointeur sur char, propre si possible
    Par wanecque dans le forum C++
    Réponses: 7
    Dernier message: 18/10/2014, 01h22
  2. Réponses: 2
    Dernier message: 15/03/2014, 20h18
  3. Réponses: 7
    Dernier message: 04/12/2012, 19h02
  4. Réponses: 1
    Dernier message: 22/12/2009, 11h40
  5. Sizeof d'un pointeur sur char ...
    Par Mike888 dans le forum C
    Réponses: 8
    Dernier message: 03/11/2005, 13h04

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