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: modification d'une variable 'const'


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut Problème: modification d'une variable 'const'
    Bonjour à tous,

    je suis débutant en C++, et pour cela j'essaye de faire quelques exercices très simples... du moins c'est ce que je pensais

    Car je suis tombé sur une erreur et je ne comprends pas du tout ce qu'il se passe!

    Je souhaite implémenter le jeu du pendu, et donc je commence par initialiser le mot secret et la réponse:

    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
     
    void initAnswer(const int size, char answer[])
    {
        for(int i = 0; i < size; i++)
        {
            answer[i] = '_';
        }
    }
     
    int main()
    {
     
        const char secret[] = "automobile";
        char answer[]       = "";
        int chance          = 5;
        bool found          = false;
        bool win            = false;
     
        cout << secret << endl;
        initAnswer(strlen(secret), answer);
        cout << secret << endl;
     
        return 0;
    }
    Je n'ai aucune erreur à la compilation, mais lorsque j'exécute j'ai les résultats suivants:
    automobile
    _________e
    Je ne comprends donc pas pourquoi la variable 'secret' a été modifiée ??? Je pense qu'il serait judicieux d'utiliser les pointeurs mais je n'en suis pas encore là...

    Merci !!

    Note: je suis sous Windows 7, avec Code::Blocks.

  2. #2
    Membre éclairé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Par défaut
    Bonjour,

    A mon avis le comportement observé vient du fait que la variable secret à la malchance ... de se trouver juste avant la variable answer .
    Le problème vient d'un débordement de tampon sans doute dû à une mauvaise interprétation de l'écriture char <variable> [].
    Quand l'on écrit ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        const char secret[] = "automobile";
        char answer[]       = "";
    l'on déclare deux tableaux statiques, alloués sur la pile et dont la taille sera déduite à la compilation (à partir des chaînes). Le code est identique à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        const char secret[11] = "automobile"; // 10 caratères + zéro terminal
        char answer[1]       = "";
    En revanche l'écriture
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void initAnswer(const int size, char answer[])
    est équivalente à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void initAnswer(const int size, char * answer)
    Du coup l'on tente d'écrire 10 caractères dans un tableau de 1, qui déborde sur le tableau secret (écrasant les 9 premiers caractères) ; à noter que l'on rentre dans le cadre d'un comportement indéfini, qui pourrait aussi faire purement et simplement planter le programme.

    Allouer un espace plus grand pour answer corrigerait le problème
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        const char secret[11] = "automobile"; // 10 caratères + zéro terminal
        char answer[11]       = "";
    mais pour un programme plus évolutif (avec secret pouvant être autre chose que "automobile" ), il vaudrait mieux utiliser des std::string gérant dynamiquement la mémoire et possédant beaucoup de fonctions très utiles.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Par défaut
    Salut,

    Lorsque tu fait
    tu accèdes à des éléments de answer[] qui n'ont pas été initialisés (car la taille de answer à son initialisation est nulle).
    Comme il n'y a pas de contrôle de dépassement des tableaux C-style, tu accèdes à un indice qui se trouve en dehors du tableau.
    Il se trouve que (par hasard), lorsque tu débordes de answer, tu tombes sur secret -> tu modifies donc secret sans le savoir.
    Mais tu pourrais très bien tomber sur n'importe quoi ou rien du tout, ton programme peut donc planter (Seg fault), ou avoir silencieusement un comportement non attendu (comme dans ton cas).

    Comment éviter ça :
    1. on est dans la section C++, faisons du C++ : les std::string sont faites pour gérer des chaînes de caractères, et supportent la modification dynamique de leur taille.
    2. si vraiment on veut utiliser des tableaux, se rappeler de ce qu'ils sont : un pointeur sur le début du tableau. Faciles à utiliser pour une taille fixe, leur utilisation en taille dynamique demande de savoir jouer proprement avec les pointeurs.

    edit : grillé , je vois qu'on est d'accord

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Tu n'as pas alloué de mémoire pour tes caractères dans answer, donc tu écris dedans, tu écrase en fait de la mémoire qui appartient à d'autres variables (ici, secret, mais ça pourrait être n'importe quoi).

    Plutôt qu'utiliser des tableaux o udes pointeurs, je te suggère d'utiliser des string (code non testé) :

    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
    #include <string>
    using namespace std;
     
     
    int main()
    {
     
        string const secret= "automobile";
        string answer(secret.size(), '_');
        int chance          = 5;
        bool found          = false;
        bool win            = false;
     
        cout << secret << endl;
        return 0;
    }
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 55
    Par défaut


    Ok, rien à dire!! Merci à tous les 3 pour vos réponses claires et précises. Ça marche tout de suite beaucoup mieux et j'ai bien tout compris

    Merci encore !!

Discussions similaires

  1. Problème d'accès à une variable
    Par khaled.mtibaa dans le forum Langage
    Réponses: 3
    Dernier message: 20/04/2006, 11h39
  2. Réponses: 2
    Dernier message: 14/04/2006, 18h40
  3. Probléme pour insérer une variable dans un champs
    Par BOUTRAIS dans le forum Access
    Réponses: 2
    Dernier message: 11/04/2006, 22h45
  4. [Eclipse 3.1]Modification d'une variable
    Par thecaptain dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 18/01/2006, 09h17
  5. Réponses: 2
    Dernier message: 29/08/2005, 16h35

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