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 :

Variable qui change de valeur "toute seule"


Sujet :

C++

  1. #1
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut Variable qui change de valeur "toute seule"
    Bonjour,

    j'ai un petit problème avec une variable qui avant l'appel d'une fonction vaut 7 et qui après vaut 3.

    Non, évidemment je ne l'ai pas passé en référence, elle n'est qu'en entrée de la fonction.

    Le plus drôle c'est que quand je l'affiche à la fin de la fonction elle vaut bien 7.

    C'est dans le programme principal qu'elle vaut 3.

    La variable en question s'appelle nbS

    L'entête de la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void Mafonction( int tab[TailleMax][TailleMax], int nbS, int T[N][TailleMax]){
     
    // J'affiche nbS à la sortie de cette fonction, elle vaut 7
    }
    Dans le programme principal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    cout<<"nbS = "<<nbS<<"\n"; // Ici nbS = 7
    mafonction(tab, nbS, T);
    cout<<"nbS = "<<nbS<<"\n"; //Ici nbS = 3
    Avez vous rencontré un problème similaire ?

    Merci,

    GDM.

  2. #2
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Salut

    Il nous manque des infos : si tu as alloué tes tableaux n'importe comment, l'écriture d'une valeur dedans peut écraser celle de nbS. Montre nous comment tu crées et initialise l'ensemble des variables utilisées, et aussi ce que fait la fonction

    Le comportement est il systématique ? Qu'est ce que ça donne en mode debug ?
    Find me on github

  3. #3
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Donc,

    J'ai défini mes constantes pour les bornes des tableaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define TailleMax 50
    #define N 1
    Ma fonction est définie comme cela:

    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 mafonction( int tab[TailleMax][TailleMax], int nbS, int T[N][TailleMax]){
     
    int i,j; 
    int d; 
     
    cout<<"nbS = "<<nbS<<"\n"; \\ça c'est juste pour tester nbS
     
    for(i=0; i<nbS;i++){
    deg = Degre(tab, nbS,i);
     
    T[0][i] = i; 
    T[1][i] = d; 
     
    } 
    cout<<"nbS = "<<nbS<<"\n"; \\ça c'est juste pour tester nbS
     
    }
    Dans le programme principal, voici comment je déclare les tableaux:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int tab[TailleMax][TailleMax]; 
    int nbS; // Nbre d'éléments effectif de tab.
    int T[N][TailleMax];
    Est-ce que cela vous suffit ? Par contre oui, la fonction mafonction appelle encore une autre fonction.... mais je n'ai pas eu de problème particulier avec celle ci, donc ce n'est peut-être pas la peine que je la décrive ?

    Je n'ai pas essayé le mode debug, je vais voir ça.

    Merci pour votre aide,

    GDM

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 941
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 941
    Points : 5 652
    Points
    5 652
    Par défaut
    Hoa,

    Avec N = 1, le seul premier indice de ton tableau T est 0 :

    T[1][...] n'existe pas.
    Si les cons volaient, il ferait nuit à midi.

  5. #5
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Ensuite, si ma mémoire est bonne, certains compilateur/Allocateur alloue la mémoire de façon contigüe (ça a peu être changé depuis la dernière fois ou je me suis penché sur le sujet sérieusement).

    comme tu déclare

    int tab[TailleMax][TailleMax];
    int nbS; // Nbre d'éléments effectif de tab.
    int T[N][TailleMax];
    nbS se situe en mémoire juste dérrière tab,
    si jamais en parcourant tab tu dépasse les indice max tu ira écrire la mémoire qui est derrière, donc nbs puis T.
    en fonction des compilateur/options de compilation parfois cela core dump, parfois cela passe inaperçu et deviens un bug "dormant" qui se réveille en général au mauvais moment.

    As-tu utilisé un outil (type valgrind/purify/....) pour vérifier les fuites mémoires et autre choses joyeuse du même style?
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  6. #6
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    droggo Hoa,

    Avec N = 1, le seul premier indice de ton tableau T est 0 :

    T[1][...] n'existe pas.
    Effectivement, c'est une erreur stupide, avec N = 2 ça marche très bien ! Merci beaucoup !

    J'avais oublié qu'il fallait toujours réserver n+1 cases (en comptant le 0).

    Ensuite,
    As-tu utilisé un outil (type valgrind/purify/....) pour vérifier les fuites mémoires et autre choses joyeuse du même style?
    non, en fait, je ne programme pas très souvent, juste quand j'y suis contraint comme c'est le cas aujourd'hui, alors je ne connais pas ces outils. Mais merci de me les avoir signalés, ça pourra toujours me servir.

    En tous les cas merci beaucoup, grace à vous ma variable reste bien à 7 !

    GDM

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut,
    Citation Envoyé par GDMINFO Voir le message
    Effectivement, c'est une erreur stupide, avec N = 2 ça marche très bien ! Merci beaucoup !

    J'avais oublié qu'il fallait toujours réserver n+1 cases (en comptant le 0).
    D'où est ce que ca vient, ca

    Tu dois réserver n+1 cases pour... les chaines de caractères, parce que, classiquement, les fonctions C qui les manipulent considère que le caractère '\0' représente le ce qui suit le dernier caractère.

    Par contre, si tu as besoin de N eniters ou de N Trucs, il n'y a strictement aucune raison de réserver N+1 éléments

    Par contre, tu dois t'assurer que la logique prenne le cas particulier où N vaut 1 en compte...

    Classiquement, étant donné que les tableaux C style ne connaissent pas leur taille, tu devrait donc, également, faire en sorte que la valeur de N soit transmise en argument à la fonction, et ne tenter le deuxième accès (T[1][i] = d; ) que... si N est exclusivement plus grand que 1
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Bon bon bon... merci beaucoup pour ces infos supplémentaires...

    La prochaine fois je réfléchirai davantage avant de parler

    GDM.

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Citation Envoyé par GDMINFO Voir le message
    Bon bon bon... merci beaucoup pour ces infos supplémentaires...

    La prochaine fois je réfléchirai davantage avant de parler

    GDM.
    Excuses moi si je t'ai un peu semblé agressif dans ma réponse

    Mais il me semblait important d'attirer ton attention sur un fait particulier:

    Lorsque tu manipule une chaine de caractères "C style" (car, en C++, on préférera quand même utiliser la classe string, disponible dans l'espace de noms std), le caractère '\0' (caractère à valeur nulle ) représente la fin de la "chaine utile" (la chaine qui représente effectivement quelque chose).

    On pourrait assez facilement comparer la mémoire d'un ordinateur à une sorte de grande bande sur laquelle se trouvent les différentes cases mémoires, et il faut comprendre que les différentes fonctions qui manipulent les chaines de caractères "C style" se "baladent" sur cette bande d'une case à l'autre.

    Le fait est que, lorsque les fonctions arrivent à la dernière adresse mémoire accessible sur le système, elle vont recommencer au début de celle-ci sans se poser plus de question que cela.

    La seule chose qui fait que ces fonctions s'arrêtent, c'est la présence du caractère nul.

    C'est ainsi, si tu "oublie" de donner la valeur 0 au caractère qui suit le dernier caractère utile de ta chaine que tu peut arriver, lors d'un simple affichage à l'affichage d'une série de caractères plus ou moins cabalistiques, suivi d'un "THIS PROGRAM CANNOT BE RUN blablabla", simplement parce que la fonction d'affichage n'a pas croisé le caractère nul et qu'elle a continué à afficher... la mémoire occupée par une autre application

    Et si le malheur veut qu'il n'y ait aucun équivalent de caractère nul dans tout ce qui est assimilable à de la mémoire dans de ton ordinateur, tu est littéralement parti pour profiter de l'affichage en boucle de l'ensemble de ton système (mémoire, disques durs et périphériques compris)

    Mais ce qu'il est important de comprendre, c'est que la présence de ce caractère nul n'est requise que... pour les fonctions de manipulation de chaines de caractères, parce que l'idée de base est de pouvoir se contenter de demander à l'utilisateur de passer un pointeur sur char sans forcément l'obliger à fournir la taille de la chaine de caractères en plus (bien qu'il existe des versions de ces fonctions qui le demande).

    Autrement, si tu as besoin d'un tableau de N éléments, quels qu'ils soient, tu peux parfaitement le déclarer sous la forme de type tab[N].

    tu disposera effectivement des N éléments, même si tu y accédera avec des indices compris entre 0 et N-1
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre habitué Avatar de GDMINFO
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    350
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 350
    Points : 160
    Points
    160
    Par défaut
    Encore une fois merci beaucoup de ces compléments fort intéressants

    Et pas de soucis, je n'avais pas trouvé la précédente réponse "agressive", c'est juste que je ne me suis pas trouvé très malin sur ce coup là, d'où ma réponse

    GDM.

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

Discussions similaires

  1. Variable qui change de valeur à chaque appel de fonction
    Par bpascal123 dans le forum Débuter
    Réponses: 5
    Dernier message: 12/03/2010, 12h47
  2. Variable qui change de valeur toute seul :(
    Par lcfseth dans le forum C
    Réponses: 12
    Dernier message: 22/12/2007, 13h25
  3. Réponses: 1
    Dernier message: 23/04/2007, 14h22
  4. Réponses: 6
    Dernier message: 18/01/2007, 11h24

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