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 d'un paramètre de fonction perdu


Sujet :

C

  1. #1
    Nouveau candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1
    Par défaut Pointeur d'un paramètre de fonction perdu
    Salut à tous,

    j'ai une fonction InsereDansListe rien de plus normal qui doit commme son nom l'indique inserer un pointeur vers un element dans une liste.

    Le probleme c'est que lorsque je passe un pointeur sur une liste vide ou même pleine et que j'alloue un emplacment mémoire pour la stocker, je perd le pointeur quand je sors de la fonction et c'est comme si javai pisser dans un violon.

    Pourtant, je pensai qu'en faisant un pointeur cela conserverai mes opérations même à la sortie de la fonction.

    Voila la fonction :
    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
     
    int InsereDansListe(Liste *L, Tache *Nouvelle) //insérer une nouvelle tache dans la liste L.
    {
    Liste* New = (Liste*)malloc(sizeof(struct liste));
    if (New == NULL)
    return 0;
    InitListe(New);
     
    New->t = Nouvelle; //pointeur sur la tâche
    if (ListeVide(L)){
    L = New;
    }
    else {
    while (L->suivant != NULL){
    L = L->suivant;
    // Si la tâche est déjà présente dans la liste
    if (L->t == Nouvelle){
    free(New);
    return 0;
    }
    }
    L->suivant = New;
    }
    return 1;
    }
    Merci d'avance à ceux qui me répondront

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par solid360
    Salut à tous,

    j'ai une fonction InsereDansListe rien de plus normal qui doit commme son nom l'indique inserer un pointeur vers un element dans une liste.

    Le probleme c'est que lorsque je passe un pointeur sur une liste vide ou même pleine et que j'alloue un emplacment mémoire pour la stocker, je perd le pointeur quand je sors de la fonction et c'est comme si javai pisser dans un violon.

    Pourtant, je pensai qu'en faisant un pointeur cela conserverai mes opérations même à la sortie de la fonction.
    En C, tout est passé par valeur. Donc toute modification à un paramètre ne modifiera pas la valeur de l'argument au niveau de la fonction appelante.

    Donc modifier L ne changera pas sa valeur dans la fonction qui a appelé cette fonction.

    Il faudra retourner la valeur de la nouvelle liste ou alors passer un pointeur vers le début de la liste pour permettre de le changer...

    Ceci donne donc deux grandes solutions :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Liste* InsereDansListe(Liste *L, Tache *Nouvelle) ;
    int InsereDansListe(Liste **L, Tache *Nouvelle) ;
    avec une préférence pour la première solution.

    Jc

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 194
    Par défaut
    juste une remarque, si la tache que tu veux ajouter correspond à la premiere de la liste, tu la rajoutes une deuxieme fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    sortie = 0;
    do
    {
      if (L->t == Nouvelle)
      {
        free(New);
        return 0;
      }  
      if (L->suivant == NULL)
        sortie = 1;
      else
         L = L->suivant
    } while (!sortie);

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Salut,

    Lorsque tu passes l'adresse vers le 1er élément de ta liste à InsereDansListe, tu passes en fait cet argument par valeur et toute modification telle que L = New si L vaut NULL sera sans effet sur ta liste originale. Tu dois déclarer le paramètre formel L comme un pointeur sur pointeur sur Liste et appeler InsereDansListe avec le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int InsereDansListe(Liste **Ls, Tache *Nouvelle);
    /*...*/
    Tache *p_tache = Tache_new(); /* Tache_new permet d'initialiser maTache*/
    Liste *p_liste = NULL;
    int err_statut;
     
    err_statut = InsereDansListe(&p_liste, p_tache);
    De cette manière, l'adresse contenue dans le pointeur p_liste peut-être modifié par la fonction. Je préfère toutefois la 1ère solution de fearyourself.
    Voici InsereDansListe modifiée:

    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
     
    int InsereDansListe(Liste **Ls, Tache *Nouvelle) 
    {
        Liste *L;
        Liste *New;
     
        L = *Ls;
     
        /* -TC- Il n'est pas conseillé de caster le retour de malloc. J'ai remplacé
         * Liste* New = (Liste*)malloc(sizeof(struct list)); dans la ligne ci-dessous
         */
        New = malloc(sizeof(*New));
        if (New == NULL) {
            return 0; /* -TC- Si malloc échoue, ta fonction termine avec un code d'erreur . C'est ton choix... */
        }
        InitListe(New); /* -TC- Initialise les champs de New à une valeur nulle? */
     
     
        New->t = Nouvelle; 
        if (ListeVide(L)){
            L = New; 
        }
        else {
            while (L->suivant != NULL){
                L = L->suivant;
                /* -TC- Ici, tu compares bien des adresses */
                if (L->t == Nouvelle){
                    free(New);
                    return 0; /* -TC-Ici, tu retourne le même code d'erreur que lorsque malloc échoue, aïe! */
                }
            }
            L->suivant = New;
        }
        *Ls = L;
        return 1; /* -TC-J'ai tendance à retourner 0 lorsque tout est OK! */
    }
    Bonne chance et meilleures salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. Réponses: 13
    Dernier message: 21/03/2009, 20h49
  2. Réponses: 3
    Dernier message: 22/07/2008, 10h46
  3. Pointeurs et paramètres de fonction
    Par tom31 dans le forum Débuter
    Réponses: 2
    Dernier message: 12/01/2008, 20h58
  4. Réponses: 10
    Dernier message: 04/01/2006, 16h57
  5. Paramètres de fonction : pointeurs ou valeurs ?
    Par Xandar dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 30/11/2005, 16h50

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