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 :

Adresse de pointeur, d'un tableau


Sujet :

C

Vue hybride

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Par défaut Adresse de pointeur, d'un tableau
    Bonjour,
    Voilà je sèche sur un problème d'adresse mémoire (et je suis sur que la réponse est évidente...)
    Voilà un exemple de 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
     
    void ma_fct(char **ip_str)
    {
        strlen(ip_str[0]);
    }
     
    int main()
    {
    char p_str[10];
    char *p = NULL;
     
    strcpy(p_str, "KO");
    p = p_str;
     
    ma_fct(&p);
    ma_fct(&p_str);
    return 0;
    }
    Bien évident, ça plante sur le 2ème appel à ma_fct.
    j'ai fait affiché les adresses p == p_str == 0x00124575
    j'ai fait affiché l'adresse de &p == 0x00111111
    j'ai fait affiché l'adresse de &p_str et là ça se gâte ! Visual Studio me donne 0x00124575 et il n'arrive pas à récupérer mon "KO"

    En gros je n'arrive pas à récupérer l'adresse de ma variable p_str. Pourquoi?
    Je suis bien d'accord qu'en faisant &p_str j'ai un type char*[10] mais en quoi ça m'empêche d'avoir son adresse?
    Maintenant ce n'est pas réellement un problème car je passe par p mais j'aimerai savoir pourquoi ça ne peut pas fonctionner...

    merci pour l'explication

    PS: dans mon code, ma_fct n'est pas exactement celle là, elle attend un tableau de chaînes de caractères (donc bien un char**) de taille N mais mon problème est que je n'ai pas de tableau mais une simple chaîne statique. Donc je pensais qu'en passant l'adresse de mon tableau statique et en donnant un taille de N == 1 je pourrais m'en sortir mais ce n'est pas le cas: je dois passer par un pointeur intermédiaire.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par polonain2 Voir le message
    Bonjour,
    Voilà je sèche sur un problème d'adresse mémoire (et je suis sur que la réponse est évidente...)
    Voilà un exemple de 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
     
    void ma_fct(char **ip_str)
    {
        strlen(ip_str[0]);
    }
     
    int main()
    {
    char p_str[10];
    char *p = NULL;
     
    strcpy(p_str, "KO");
    p = p_str;
     
    ma_fct(&p);
    ma_fct(&p_str);
    return 0;
    }
    Bien évident, ça plante sur le 2ème appel à ma_fct.
    Comment le sais-tu ? Il n'y a aucun printf() permettant de voir ce qui se passe !!!
    Citation Envoyé par polonain2 Voir le message
    j'ai fait affiché les adresses p == p_str == 0x00124575
    j'ai fait affiché l'adresse de &p == 0x00111111
    j'ai fait affiché l'adresse de &p_str et là ça se gâte ! Visual Studio me donne 0x00124575 et il n'arrive pas à récupérer mon "KO"

    En gros je n'arrive pas à récupérer l'adresse de ma variable p_str. Pourquoi?
    Je suis bien d'accord qu'en faisant &p_str j'ai un type char*[10] mais en quoi ça m'empêche d'avoir son adresse?
    Parce que l'adresse d'un tableau n'a pas vraiment de sens car un tableau n'existe pas vraiment en tant qu'entité. La variable p_str n'existe pas. Ce n'est qu'un raccourci vers l'adresse du premier élément => p_str=&p_str[0].
    Et donc &p_str ne signifie rien...

    Citation Envoyé par polonain2 Voir le message
    Maintenant ce n'est pas réellement un problème car je passe par p mais j'aimerai savoir pourquoi ça ne peut pas fonctionner...
    Si tu passes par p alors effectivement p contient &p_str[0] et tout va bien, tu peux utiliser l'un ou l'autre indifféremment. Mais si tu utilises &p, alors tu récupères juste l'adresse d'un pointeur qui, lui, contient l'adresse d'un caractère. Bien évidemment encore, tu peux arriver à suivre le fil pour retrouver ledit caractère. Mais en revanche, bien que l'analogie soit tentante, elle est fausse et &p ne correspond pas du tout à &p_str.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    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
    Je suis bien d'accord qu'en faisant &p_str j'ai un type char*[10]
    Non, en fait c'est un char (*)[10] : adresse d'un tableau de 10 char, type en désaccord avec celui du paramètre ip_str (char **), ce que doit signaler le compilateur.

    Si on passe outre aux avertissements justifiés du compilateur, &p_str aura probablement une valeur correspondant à celle du début du tableau p_str (je ne pense pas que cela soit rendu obligatoire par la norme) et, dans la fonction, ip_str[0] aura pour valeur non l'adresse du début du tableau mais le code de la chaine "KO" (+ éventuellement des trucs en plus) contenue dans le tableau et on ira dans les décors.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Par défaut
    Comment le sais-tu ? Il n'y a aucun printf() permettant de voir ce qui se passe !!!
    j'utilise le debugger de Visual Studio.

    Non, en fait c'est un char (*)[10]
    . C'est ce que je voulais dire au temps pour moi.

    dans la fonction, ip_str[0] aura pour valeur non l'adresse du début du tableau mais le code de la chaine "KO"
    . Oui je te le confirme.

    Ce n'est qu'un raccourci vers l'adresse du premier élément => p_str=&p_str[0].
    . Ca j'en avais bien conscience mais c'est le fait qu'elle n'existe pas réellement en tant qu'entité qui me pose problème. Pour moi si je déclare une variable elle a forcément une adresse en mémoire (quel que soit son contenu).

    Merci pour vos explications, je vais cogiter tout ça.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    En complément d'info:
    p_str = &p_str[0]
    Les valeurs sont égales, mais le type de départ est différent:
    • p_str est de type char[10], mais bénéficie d'une conversion implicite en char*
    • &p_str[0] est tout le temps de type char*

    Et pour compliquer encore plus les choses, &p_str possède encore la même valeur que les deux autres, mais un type différent char (*)[10]
    Et on peut repérer le problème si on les incrémente:
    (&p_str)+1 =/= (p_str)+1 == (&p_str[0])+1
    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.

  6. #6
    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
    En complément d'info:
    p_str = &p_str[0]
    L'ennui est que cette expression est illégale en C (p_str désigne un tableau et est non modifiable) ce qui peut prêter à confusion.
    Il vaut mieux écrire

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par polonain2 Voir le message
    . Ca j'en avais bien conscience mais c'est le fait qu'elle n'existe pas réellement en tant qu'entité qui me pose problème. Pour moi si je déclare une variable elle a forcément une adresse en mémoire (quel que soit son contenu).
    En déclarant char p_str[10], tu déclares 10 variables nommées
    p_str[0] de type char
    p_str[1] de type char
    p_str[2] de type char
    ...
    p_str[9] de type char
    Donc tu ne devrais pas avoir de problème existentiel. Tu as déclaré 10 variables qui ont toutes une adresse, comme tu le demandes.

    De plus, (et ça c'est gratuit et en complément), tu as un truc nommé "p_str" qui équivaut à l'adresse de la variable p_str[0]. Et, pour t'aider à comprendre, tu peux considérer ce p_str non pas comme variable mais simplement comme alias. Donc là non plus tu ne devrais pas avoir de problème existentiel puisque là, ce p_str n'étant pas vraiment variable, il n'a pas vraiment à avoir d'adresse (attention tous les pros du C qui vont venir crier à l'hérésie, je précise qu'il s'agit ici d'une simple image destinée à faire passer plus simplement un concept assez difficile et non une explication profonde du fonctionnement du langage...)

    Citation Envoyé par Médinoc Voir le message
    En complément d'info:

    Et on peut repérer le problème si on les incrémente:
    (&p_str)+1
    Intéressant. Ca ne m'avait jamais traversé l'esprit d'essayer ça. Mais étant donné que "&p_str" n'a pas vraiment de sens, c'est compréhensible que le compilo, en essayant de te satisfaire malgré tout, parte complètement à l'ouest sur cette instruction...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    &p_str possède parfaitement un sens, vu que son type est déclarable. Et même typedefable. C'est juste un type qu'on n'utilise pas souvent.
    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.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    &p_str possède parfaitement un sens, vu que son type est déclarable. Et même typedefable.
    Le terme "sens" représentait, sans ma phrase, une notion s'apparentant à "utile" ou "utilisé"...

    Citation Envoyé par Médinoc Voir le message
    C'est juste un type qu'on n'utilise pas souvent.
    "Pas souvent" ? J'aimerais bien avoir un exemple où cela a été nécessaire...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Question : L'adresse du pointeur sur un tableau
    Par al.spec dans le forum Débuter
    Réponses: 4
    Dernier message: 24/09/2010, 19h08
  2. pointeur pour un tableau 2d
    Par olive14 dans le forum C
    Réponses: 6
    Dernier message: 07/05/2005, 15h02
  3. Références et pointeurs sur un tableau
    Par smag dans le forum C++
    Réponses: 2
    Dernier message: 01/03/2005, 20h29
  4. [LG]adresse de pointeur
    Par grand's dans le forum Langage
    Réponses: 7
    Dernier message: 29/05/2004, 10h27
  5. Pointeur vers un tableau
    Par Nikos dans le forum C
    Réponses: 3
    Dernier message: 09/12/2002, 00h43

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