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 :

Chaine et pointeur de char: pourquoi ca marche?


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Enseignant retraité
    Inscrit en
    Juin 2004
    Messages
    547
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant retraité

    Informations forums :
    Inscription : Juin 2004
    Messages : 547
    Par défaut Chaine et pointeur de char: pourquoi ca marche?
    Bonjour,

    je ne comprends pas pourquoi ce bout de code non seulement passe à la compilation, mais en plus s'exécute comme il faut:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    char* a;
    char* b;
    a="bonjour";
    std::cout << a << endl;
    b="salut a tous";
    a=b;
    std::cout << a;
    Mon compilateur (visual c++ 2008 express) génère-t-il automatiquement du code permettant de gérer dynamiquement la mémoire allouée aux chaines?

    Merci

  2. #2
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Avec un compilateur C cela fonctionne également. Lors de l'instruction a = "bonjour", le compilateur alloue automatiquement de la mémoire pour cette chaine de caractère. Ceci est appliquable aux chaine de caractères uniquement.

    Cependant cet espace mémoire ne peut être modifié. Je ne sais plus pourquoi, mais il me semble que le compilateur le générant automatiquement, le programmeur n'a pas connaissance de l'adresse de la chaine et il ne peut plus la modifier par la suite. C'est pourquoi il faut déclarer ce type de variable en tant que const: L'écriture correcte serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char* a = "bonjour";
    Le code suivant génère une erreur de segmentation dû au fait de la modification de la mémoire contenant la chaine allouée par le compilateur
    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
    #include <stdio.h>
    #include <string.h>
     
    int main() {
            char* a;
     
            a = "bonjour";
     
            printf(a);
            fflush(stdout);
     
            strcpy(a, "salut");
     
            printf(a);
            fflush(stdout);
            return 0;
    }

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 400
    Par défaut
    La mémoire n'est pas allouée dynamiquement à l'exécution, mais statiquement. La chaîne est stockée directement dans une zone de données en lecture seule, dès le chargement du programme. En fait, dans ce code, a est l'équivalent d'un pointeur vers une variable globale, mais une variable globale qui serait en lecture seule bien qu'elle ne soit pas déclarée const.

    Si tu compiles avec gcc, tu peux activer l'option -Wwrite-strings, et les chaînes deviendront const: Tu auras une erreur de compilation en C++ (ou un warning en C) sur la ligne du a="bonjour"; si a n'est pas un pointeur const.

    Pourquoi les chaînes ne sont-elles pas const dès le début? Je crois que c'est pour la compatibilité avec les plus vieux codes. Je dis peut-être des c*nneries, mais il me semble qu'en un temps que tu ne peux connaitre, le mot-clé const n'existait pas en C.
    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.

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant retraité
    Inscrit en
    Juin 2004
    Messages
    547
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant retraité

    Informations forums :
    Inscription : Juin 2004
    Messages : 547
    Par défaut
    Merci pour vos réponses.

    Je savais bien qu'on pouvait faire char* a = "bonjour"; mais je ne savais pas que l'on pouvais différer l'affectation de la chaine à a.

    Si je comprends bien, le compilateur va analyse le source, voir le b = "salut a tous", puis le a = b pour savoir quelle est la taille de la mémoire à réserver pour faire pointer a dessus.


    En tout cas, en remplaçant le
    a = "bonjour";
    par
    cin >> a;
    ça plante bien. Ouf!

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Par défaut
    Citation Envoyé par jackk Voir le message
    Je savais bien qu'on pouvait faire char* a = "bonjour"; mais je ne savais pas que l'on pouvais différer l'affectation de la chaine à a.
    La variable a n'est pas une chaine, c'est un pointeur vers un caractère.

    Si je comprends bien, le compilateur va analyse le source, voir le b = "salut a tous", puis le a = b pour savoir quelle est la taille de la mémoire à réserver pour faire pointer a dessus.
    Non, aucune chaine n'est alloué dynamiquement. Le code est équivalent à quelque chose comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    static char const _string1[] = "bonjour";
    static char const _string2[] = "salut";
     
    char* a;
    char* b;
    a=(char*)_string1; // fait pointer a vers le premier caractère de _string1
    std::cout << a << endl;
    b=(char*)_string2; // fait pointeur b vers le premier caractère de _string2
    a=b; // fait pointer a vers le même caractère que b (_string2)
    std::cout << a;

  6. #6
    Membre chevronné
    Homme Profil pro
    Enseignant retraité
    Inscrit en
    Juin 2004
    Messages
    547
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant retraité

    Informations forums :
    Inscription : Juin 2004
    Messages : 547
    Par défaut
    La variable a n'est pas une chaine, c'est un pointeur vers un caractère.
    Je n'ai jamais dit que a était une chaine. Par contre "bonjour" en est bien une.

    Non, aucune chaine n'est alloué dynamiquement. Le code est équivalent à quelque chose comme ça
    dans mon message #4, je ne parle plus de gestion dynamique de la mémoire puisque je parle du compilateur.

Discussions similaires

  1. Réponses: 2
    Dernier message: 15/03/2014, 21h18
  2. Sizeof d'un pointeur sur char ...
    Par Mike888 dans le forum C
    Réponses: 8
    Dernier message: 03/11/2005, 14h04
  3. [OLE DB] pourquoi ca marche pas ??
    Par aurel89 dans le forum MFC
    Réponses: 3
    Dernier message: 09/09/2005, 18h23
  4. Accept : pourquoi ça marche pas ?
    Par doudblast dans le forum Linux
    Réponses: 16
    Dernier message: 08/03/2005, 12h48
  5. Chaines et pointeurs mais pas "const"
    Par hpfx dans le forum C
    Réponses: 9
    Dernier message: 05/10/2003, 21h23

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