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 :

Valeurs de int différentes à l'affichage mais les mêmes lors d'une comparaison


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut Valeurs de int différentes à l'affichage mais les mêmes lors d'une comparaison
    Bonjour,

    Voici le code C suivant :

    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
     
                char* test = (char*)((subSequence(n->attribute, i, i+tailleKmer-1))->tab);
                printf("Contenu de test[0] = %d \n",test[0]);
     
                sll_s* ll1 =  (sll_s*) hash_search(index, test);
                Duo* d1 = sll_data(ll1);
                int* int1 = (int*)d1->data2;
                printf("Adresse de d1->data2 : %p \n\n", &(d1->data2));
                printf("Valeur de int1 = %d \n\n",*int1);
     
                char* test2 = (char*)((createSequence("TCCC"))->tab);
                printf("Contenu de test2[0] = %d \n",test2[0]);
     
                sll_s* ll2 =  (sll_s*) hash_search(index, test2);
                Duo* d2 = sll_data(ll2);
                int* int2 = (int*)(d2->data2);
                printf("Adresse de d2->data2 : %p \n\n", &(d2->data2));
                printf("Valeur de int2 = %d \n \n",*int2);
     
                if (*int1 == *int2) printf("int1 et int2 sont identique ! \n");
                else printf("int1 et int2 sont différents ! \n");
    Ne vous occupez pas des fonctions subSequence() et createSequence() : ce sont deux manières différentes d'obtenir un tableau d'unsigned char à une case, contenant le chiffre 213, qui une fois casté en char donne -43.

    Voici le résultat affiché :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Contenu de test[0] = -43
    Adresse de d1->data2 : 0x211ea68
     
    Valeur de int1 = 2
     
    Contenu de test2[0] = -43
    Adresse de d2->data2 : 0x211ea68
     
    Valeur de int2 = -1
     
    int1 et int2 sont indentique !
    Je ne comprend pas pourquoi quand j'affiche int1 et int2, leurs valeurs sont différentes mais quand je les compares, elles sont identiques ... Elles proviennent pourtant de la même adresse à la base (avant le cast) non ? Sa me pose un maximum de soucis pour la suite de mon programme et j'avoue ne plus rien y comprendre ...

    Si quelqu'un pouvait éclairer ma lanterne, ce serait super sympa de sa part
    Je vous remercie d'avance.

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2007
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 179
    Par défaut
    Tu affiches *int1 et *int2 et tu compares int1 et int2

  3. #3
    Membre chevronné
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Par défaut
    Tout ce que je comprends, avec le code dont je dispose, c'est qu'ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (int1 == int2) printf("int1 et int2 sont identique ! \n");
    tu compares deux POINTEURS (donc deux adresses) et non les valeurs pointées, pour lequel tu ferais plutot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (*int1 == *int2) printf("int1 et int2 sont identique ! \n");
    Vu le peu d'informations dont on dispose sur la structure Duo etc, on peut imaginer le contenu des valeurs pointées change, sans pour autant que le pointeur change aussi.

  4. #4
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut
    Autant pour moi, j'ai fait un milliard de tests et testés pas mal de chose pas vraiment pertinentes a vrai dire. Je fais la modif sur le code : ce sont bien les valeurs que je voulait comparer et non les pointeurs

    Donc la ligne suivant est valide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (*int1 == *int2) printf("int1 et int2 sont identique ! \n");
    Du coup, je ne comprend pas ...

  5. #5
    Membre chevronné
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Par défaut
    C'est déjà ça. Cependant, ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int* int2 = (int*)(d2->data2);
    printf("Adresse de d2->data2 : %p \n\n", &(d2->data2));
    printf("Valeur de int2 = %d \n \n",*int2);
    tu dis que d2->data est un pointeur vers un int.
    Mais quand tu affiches l'adresse, tu affiches l'adresse du pointeur lui même, pas l'adresse qu'il contient.
    Ca a peut-être un sens, mais ça aiderait beaucoup d'avoir la definition de la structure Duo.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Puisqu'il s'agit de pointeurs, pointant sur la même zone mémoire, c'est logique que leur valeur soit identique, puisque c'est exactement la même.
    Une zone mémoire est toujours égale à elle-même, encore heureux !

    Que la valeur de la zone mémoire change entre temps, on n'y est pour rien, c'est à toi de voir quelle fonction modifie ça.

    Je ne comprend pas pourquoi quand j'affiche int1 et int2, leurs valeurs sont différentes mais quand je les compares, elles sont identiques ...
    Tu les affiches pas au même moment..
    Si tu prends une boîte et y cache un billet de 5€, et qu'après tu tripotes la boîte et remplaces le billet de 5€ par un de 10€, ou la prête à un ami qui réalisera cette opération, seras-tu surpris que la même boîte ne cache pas le même billet ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre actif
    Inscrit en
    Décembre 2009
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Décembre 2009
    Messages : 95
    Par défaut
    Alors voici ma structure Duo et son constructeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct Duo
    {
        void* data1;
        void* data2;
    } Duo;
    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
     
    Duo* createDuo(void* data1, void* data2){
        Duo* d = malloc(sizeof(Duo));
     
        if(d != NULL){
            d->data1 = data1;
            d->data2 = data2;
        }
        else {
            fprintf (stderr, "insufficient memory to create a duo\n");
            exit (EXIT_FAILURE);
        }
     
        return d;
    }
    @Bousk : le problème étant que la bonne valeur que j'essaye de récupérer est 2, donc int1, et int2 que je cherche après me retourne une mauvaise valeur, à savoir -1. Or si je cherche int2 avant int1 je vais avoir le même problème : int2 va me retourner -1, je vais chercher int1 qui va me retourner 2 ...

    Donc si j'essaye ce code :

    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
     
                char* test2 = (char*)((createSequence("TCCC"))->tab);
                printf("Contenu de test2[0] = %d \n",test2[0]);
     
                sll_s* ll2 =  (sll_s*) hash_search(index, test2);
                Duo* d2 = sll_data(ll2);
                int* int2 = (int*)(d2->data2);
                printf("Adresse de d2->data2 : %p \n\n", &(d2->data2));
                printf("Valeur de int2 = %d \n \n",*int2);
     
                char* test = (char*)((subSequence(n->attribute, i, i+tailleKmer-1))->tab);
                printf("Contenu de test[0] = %d \n",test[0]);
     
                sll_s* ll1 =  (sll_s*) hash_search(index, test);
                Duo* d1 = sll_data(ll1);
                int* int1 = (int*)d1->data2;
                printf("Adresse de d1->data2 : %p \n\n", &(d1->data2));
                printf("Valeur de int1 = %d \n\n",*int1);
     
                if (*int1 == *int2) printf("int1 et int2 sont identique ! \n");
                else printf("int1 et int2 sont différents ! \n");
    J'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Contenu de test2[0] = -43
    Adresse de d2->data2 : 0x211ea68
     
    Valeur de int2 = -1
     
    Contenu de test[0] = -43
    Adresse de d1->data2 : 0x211ea68
     
    Valeur de int1 = 2
     
    int1 et int2 sont indentique !
    Je te met ici malgré tout les fonctions sll_data() et hash_search() mais je ne comprend pas comment elle ferait pour modifier les données qu'on leur passe en paramètre :

    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
     
    void *hash_search (hash_s * p_table, const char *key)
    {
       void *data = NULL;
     
       if (p_table != NULL && key != NULL)
       {
          int i = 0;
     
          while (i < p_table->size)
          {
             if (strcmp (p_table->p_cell[i].key, key) == 0)
             {
                data = p_table->p_cell[i].data;
                break;
             }
             i++;
          }
       }
       return (data);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void *sll_data (sll_s * p_sll)
    {
       return ((p_sll && p_sll->list) ? p_sll->list->data : NULL);
    }

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    ssl_data renvoie visiblement le meme pointeur pour les deux appels en ayant toute fois modifie la valeur pointee. Comme tu conserves un pointeur et non la valeur, c'est normal que le deuxieme appel a ssl_data modifie la valeur pointee par le pointeur retourne par le meme appel.

    Tu as l'equivalent de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int foo = 42;
    int* int1 = &foo;
    foo = 36;
    int* int2 = &foo;
    if (*int1 == *int2)
       printf("int1 et int2 sont identique ! \n");
    else
        printf("int1 et int2 sont différents ! \n");
    ou il n'est pas surprenant d'avoir l'affichage "int1 et int2 sont identiques".

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Puisque tes paramètres ne sont pas const, rien n'assure qu'ils ne seront pas modifiés.
    Modifies-les pour qu'ils soient const, et tu verras peut-être une alerte du compilo qui t'indiquera où se situe la coquille.

    le problème étant que la bonne valeur que j'essaye de récupérer est 2, donc int1, et int2 que je cherche après me retourne une mauvaise valeur, à savoir -1.
    Nous on sait pas ce que tu cherches, ni où tu le cherches.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char* test2 = (char*)((createSequence("TCCC"))->tab);
    sll_s* ll2 =  (sll_s*) hash_search(index, test2);
                char* test = (char*)((subSequence(n->attribute, i, i+tailleKmer-1))->tab);
                sll_s* ll1 =  (sll_s*) hash_search(index, test);
    Tu utilises deux fois hash_search avec des paramètres différents, on ne sait pas d'où sortent et ce que valent test ni test2, ni si elles sont identiques ou non; Mais il n'est pas aberrant de penser que le hash_search ne retourne pas 2 pour test2, et qu'il le sorte pour test1. D'ailleurs c'est ce qu'il fait : ne pas retourner 2 pour test2.

    Il serait temps de passer en debug pas à pas, voire si tu es sous visual studio en memory breakpoint, très pratique pour ce genre de cas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Afficher les colonnes lors d'une extraction oracle
    Par griese dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 08/12/2006, 16h20
  2. [MySQL] Récupérer les données lors d'une requete
    Par gguiz dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 03/11/2006, 13h34
  3. Petit probleme avec les Border lors d'une sauvegarde
    Par Mike888 dans le forum Interfaces Graphiques en Java
    Réponses: 7
    Dernier message: 06/06/2006, 09h33
  4. Réponses: 2
    Dernier message: 19/05/2006, 12h22
  5. Combler les trous lors d'une suppression dans une table
    Par Billybongjoe dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 08/04/2004, 14h02

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