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 de référence


Sujet :

C

Vue hybride

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

    Informations forums :
    Inscription : Décembre 2009
    Messages : 45
    Par défaut Problème de référence
    Bonjour,

    Voilà mon problème:

    Je lance une méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void meilleurMouv (IlotEntier* pointeurIlot){
    IlotEntier est une structure qui est une liste de listes.

    Dans ma méthode je fais ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IlotEntier* tmpIlot1 = NULL ;
    (tmpIlot1)=(pointeurIlot);
    DeleteEntier(tmpIlot1[2].ilot,8);
    DeleteEntier est une méthode qui supprime la valeur 8 dans la liste tmpIlot1[2].ilot.

    Cela marche très bien sur ma liste tmpIlot1[2].ilot, le problème, c'est que ça modifie aussi ma liste pointeurIlot[2].ilot alors que je ne veux pas la modifier...

    Comment faire pour que seul tmpIlot1 soit modifiée et pas pointeurIlot???

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

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Salut, quand tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IlotEntier* tmpIlot1 = NULL ;
    (tmpIlot1)=(pointeurIlot);
    DeleteEntier(tmpIlot1[2].ilot,8);
    qui s'écrit plus simplement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    IlotEntier* tmpIlot1 = pointeurIlot;
    DeleteEntier(tmpIlot1[2].ilot,8);
    tmpIlot1 et pointeurIlot pointent sur la MEME zone mémoire. Donc si tu en modifies 1, tu modifies l'autre. Il faut que tu te fasses une fonction copyIlot(tmpIlot1,pointeurIlot) qui copie tous les éléments de pointeurIlot dans tmpIlot1

    Imagine, quand tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char * str1 = "toto";
    char * str2 = "toto";
    si tu fais

    la réponse est FALSe car tu compares ici les pointeurs. En revanche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (strcmp(str1,str2) == 0)
    te renverras TRUE. C'est rigoureusement la même chose pour toi entre tmpIlot1 et pointeurIlot

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 45
    Par défaut
    tmpIlot1 et pointeurIlot pointent sur la MEME zone mémoire.
    J'avais conscience de pointer la même zone de mémoire mais je ne voyais pas comment y remédier!

    Merci, je vais essayer créer une méthode de copie.

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Je te conseillerais de te documenter sur memcpy. Voici le lien : http://www.cplusplus.com/reference/c...string/memcpy/

    Voila bonne chance

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 45
    Par défaut
    J'ai réussi la méthode de copie et j'ai pu avancer dans mon projet donc merci!

    Mais voilà, je m'emmêle encore avec les pointeurs (c'est mon premier projet en C).

    J'ai une méthode:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void meilleurMouv (IlotEntier* pointeurIlot,listeTabou *mouvInterdit){
     
    AddEntiers(&pointeurIlot[0].ilot,5);
    //pointeurIlot a été modifié
    AddTabou(&mouvInterdit,5,1,6);
    //mouvInterdit a été modifié
    Quand j'exécute cette méthode dans une autre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void tabou(IlotEntier* pointeurIlot){
    	listeTabou* mouvInterdit= calloc(3,sizeof(listeTabou));
     
    meilleurMouv(pointeurIlot,mouvInterdit);
     
    //Quand je test à cet endroit, pointeurIlot reste bien modifié
    //Mais mouvInterdit garde sa valeur initiale...
    Je ne comprend pas pourquoi la modification par référence marche pour l'une des listes et pas pour l'autre...

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Salut, préfère ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    listeTabou* mouvInterdit= calloc(3,sizeof(*mouvInterdit));
    if(mouvInterdit == NULL)
    {
      // ici tu geres le cas d'erreur
    }
    à cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    listeTabou* mouvInterdit= calloc(3,sizeof(listeTabou));
    Peux-tu poster le code de AddEntiers() et AddTabou() s'il te plaît ?

  7. #7
    Expert confirmé
    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
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void meilleurMouv (IlotEntier* pointeurIlot,listeTabou *mouvInterdit){
     
    AddEntiers(&pointeurIlot[0].ilot,5);
    //pointeurIlot a été modifié
    AddTabou(&mouvInterdit,5,1,6);
    //mouvInterdit a été modifié
    Dans ce code, mouvInterdit peut avoir été modifié. Mais il faut comprendre que mouvInterdit est une variable locale qui a reçu comme valeur, au moment de l'appel de la fonction meilleurMouv(), l'adresse d'une variable X extérieure à la fonction (et de type listeTabou).
    &mouvInterdit désigne l'adresse A de cette variable locale (et non l'adresse de X).
    Dans ce code, AddTabou doit avoir pour prototype AddTabou(listeTabou **). Si ce n'est pas le cas, le compilateur doit émettre un avertissement. Il est possible que AddTabou() modifie la variable X, mais elle doit avoir été écrite dans ce sens. Sans le code de AddTabou(), il est difficile d'en dire plus.

    Pour illustrer, en éliminant ce qui est inutile à la compréhension pour simplifier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    listeTabou X;
    meilleurMouv(&X);
    ....
    void meilleurMouv (listeTabou *mouvInterdit)
    {
       // mouvInterdit est à une adresse A et contient &X :  *A == &X  ;
       AddTabou(&mouvInterdit); // On passe la valeur A
    }
    void AddTabou(listeTabou ** t)
    {
      // t contient A ;  *t == *A == &X
      **t = ... ; // == *&X == X : modifie X mais pas mouvInterdit 
      *t = ... ;  // == *A == *&mouvInterdit == mouvInterdit : modifie mouvInterdit mais pas X
    }

    Prenons maintenant le cas du AddEntiers() et de son argument &pointeurIlot[0].ilot. Là aussi, pointeurIlot est une variable locale qui a été initialisée lors de l'appel à meilleurMouv() par l'adresse d'une variable X de type IlotEntier (soit la valeur &X) ou plus vraisemblablement par l'adresse du premier élément d'un tableau X soit &X[0].
    Alors
    pointeurIlot[i] == *(pointeurIlot+i) == *(&X[0]+i) == *(&X[i]) == X[i]
    pointeurIlot[i].ilot correspond donc à X[i].ilot et &pointeurIlot[i].ilot sera l'adresse de X[i].ilot. La fonction AddEntiers() peut modifier X[i].ilot (ou pointeurIlot[i].ilot), mais pas la valeur de pointeurIlot ou de pointeurIlot[i].
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    IlotEntier X[10];
    meilleurMouv(X);
    ....
    void meilleurMouv (IlotEntier *pointeurIlot)
    {
       // pointeurIlot est à une adresse A et contient &X[0] 
       AddEntiers(&pointeurIlot[0].ilot); // On passe la valeur &X[0].ilot
    }
    void AddEntiers(... * t)
    {
      // t contient &X[0].ilot
      *t = ... ;  // modifie X[0].ilot
    }

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par salseropom Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char * str1 = "toto";
    char * str2 = "toto";
    si tu fais

    la réponse est FALSE car tu compares ici les pointeurs.
    Pas nécessairement.

    "toto" est ici une chaîne constante, il est probable qu'elle ne soit présente qu'une seule fois en mémoire et donc que str1 et str2 contiennent l'adresse de cette unique chaîne et soient donc égaux.

    J'aurais même tendance à penser qu'un compilateur n'utilisant pas la même adresse ici est de piètre qualité.

    Et au passage, il serait plus correct d'écrire char const * str1 = "toto";

Discussions similaires

  1. [VBA-E] Problème de références
    Par Elstak dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 13/07/2006, 09h04
  2. Problème de référence de classe
    Par nmathon dans le forum Delphi
    Réponses: 7
    Dernier message: 21/06/2006, 16h46
  3. [FLASH MX2004] this et problème de référence
    Par cristolb dans le forum ActionScript 1 & ActionScript 2
    Réponses: 5
    Dernier message: 03/05/2006, 22h33
  4. Problème de référence de données circulaire
    Par Wismerhill50 dans le forum Langage
    Réponses: 3
    Dernier message: 23/10/2005, 22h38
  5. problème de références _ptr dans une map STL
    Par Mr_Tyu dans le forum CORBA
    Réponses: 1
    Dernier message: 10/08/2004, 10h39

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