Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème sur des pointeur de tableaux

    20 août 2022 à 20:48:55

    Bonjour, je vous écrit car je suis actuellement entrain d'écrire un programme pour apprendre à maitriser le c++ mais je suis sur un problème que je n'arrive pas à résoudre. En fait, tout mon programme tourne autour d'une même variable qui est un tableau. Chaque classe ayant besoin de cette variable possède donc un pointeur de ce tableaux pouvant y accéder cependant lorsque j'essaye d'accéder a un pointeur le compilateur stop le programme à cause de problèmes d'accès.

    //code de la classe
    class Class {
    
    public:
      void initPointeur();
      void modifValeur();
    private:
      int (**valeur);
    };
    
    //code du fichier cpp
    
    int valeur [3] = {0, 0, 0};
    Class class;
    
    int main(){
    class.initPointeur(valeur);
    class.modifValeur();
    std::cout << valeur[0];
    }
    
    void Class:initPointeur(int valeur[]){
      this->valeur=&valeur
      (*this->valeur)[0]=10;
      //Ici modifier la valeur marche très bien
    }
    
    void Class::modifValeur(){
      (*valeur)[0]=10;
      //Lorsque je modifier la variable dans une autre fonction j'ai alors des problème d'accès alors que je suis censés pouvoir y accéder
    }

    Ce cas la est un cas simplifié de mon problème que je n'arrive pas à résoudre et je sais qu'il est possible de résoudre ce problème avec des variables externes mais je trouve cela moins propre et j'ai envie de comprendre ce langage et non de contourner à chaque fois les problèmes que je rencontre. J'espère sincèrement que vous pourrez m'aider car la je sèche complètement.



    • Partager sur Facebook
    • Partager sur Twitter
      20 août 2022 à 22:50:31

      Bonjour,

      En cherchant à donner un extrait de ton code, tu as créée un code bourré de non sens. Ça complifie notre lecture.

      Déjà on doit éviter d'utiliser les pointeurs et les tableaux bruts en C++, c'est source de problèmes inutiles et tu es en plein dedans.

      Tu n'as pas à utiliser un pointeur de pointeur, ce que tu dois stocker c'est l'adresse d'un tableau donc l'adresse de son premier élément et un pointeur sur int est ce qu'il te faut.
      Du coup, ta ligne 23 n'a aucun sens. Tu stockes l'adresse de valeur, or valeur est le paramètre reçu. Tu stacke donc l'adresse que quelque chose qui disparait dès que initPointeur() est terminée!

       En renommant, on devrait avoir le code:

      //code de la classe
      class Class {
      public:
        void initPointeur( int* tab );
        void modifValeur();
      private:
        int *tab;
      };
       
      //code du fichier cpp
        
      int main(){
         int  tableau[3] = {0, 0, 0};
         Class  la_classe;
      
         la_classe.initPointeur( tableau );
         la_classe.modifValeur();
      
         std::cout << tableau[0];
      }
       
      void  Class::initPointeur( int* tab ) {
         this->tab = tab;
         (this->tab)[0] = 10;
      }
      
      void  Class::modifValeur() {
         tab[0] = 10;
      }

      -
      Edité par Dalfab 20 août 2022 à 22:56:28

      • Partager sur Facebook
      • Partager sur Twitter

      En recherche d'emploi.

        21 août 2022 à 0:58:24

        Merci beaucoup, en fait dans mon code originale 

        Dalfab a écrit:

        Bonjour,

        En cherchant à donner un extrait de ton code, tu as créée un code bourré de non sens. Ça complifie notre lecture.

        Déjà on doit éviter d'utiliser les pointeurs et les tableaux bruts en C++, c'est source de problèmes inutiles et tu es en plein dedans.

        Tu n'as pas à utiliser un pointeur de pointeur, ce que tu dois stocker c'est l'adresse d'un tableau donc l'adresse de son premier élément et un pointeur sur int est ce qu'il te faut.
        Du coup, ta ligne 23 n'a aucun sens. Tu stockes l'adresse de valeur, or valeur est le paramètre reçu. Tu stacke donc l'adresse que quelque chose qui disparait dès que initPointeur() est terminée!

         En renommant, on devrait avoir le code:

        //code de la classe
        class Class {
        public:
          void initPointeur( int* tab );
          void modifValeur();
        private:
          int *tab;
        };
         
        //code du fichier cpp
          
        int main(){
           int  tableau[3] = {0, 0, 0};
           Class  la_classe;
        
           la_classe.initPointeur( tableau );
           la_classe.modifValeur();
        
           std::cout << tableau[0];
        }
         
        void  Class::initPointeur( int* tab ) {
           this->tab = tab;
           (this->tab)[0] = 10;
        }
        
        void  Class::modifValeur() {
           tab[0] = 10;
        }

        -
        Edité par Dalfab il y a environ 1 heure

        Merci beaucoup, en fait dans mon code originale c'est un tableau a deux dimensions que j'utilisais, je me suis alors totalement emmêler les pinceaux en voulant simplifier l'exemple avec des double pointeur inutiles. Mais j'ai pu grâce a ton exemple m'inspirer de ton code pour réécrire mon code avec le tableau à deux dimensions et c'est bon il fonctionne ! En fait, le véritable problème était le fait que j'utilisais l'adresse du tableau quand j'initialisais mon pointeur. Mais c'est justement cette partie que je ne comprends pas. D'après ce que je sais lorsque nous mettons un tableau en argument d'une fonction c'est une référence au tableau qui est utilisés dans la fonction est non une copie comme c'est le cas avec les variables par exemple. Alors pourquoi lorsque que j'écrit &valeur cela me renvoi à une autre adresse que celui du tableau initial alors qu'aucune copie du tableau n'a été faite. Pourrait tu s'il te plaît m'expliquer cette logique car je ne comprends pas du tout cette subtilité. Et encore merci de m'avoir aidé.

        • Partager sur Facebook
        • Partager sur Twitter
          21 août 2022 à 10:40:26

          Salut,

          Ceci étant dit, il est jamais bon de travailler avec des pointeurs lorsque "tout ce que tu veux", c'est manipuler des tableaux parce que C++ fournit des classes qui permettent de les gérer de manière bien plus sécurisante.

          Tu serais donc bien inspiré de t'intéresser aux classe std::array, que tu peux faire connaître du compilateur en incluant le fichier d'en-tête <array>, et qui correspond à un tableau de taille fixe (du style de int a[N] avec N défini à la compilation) et std::vector<type>, que tu peux faire connaitre du compilateur en incluant le fichier <vector>, qui correspond à un tableau dont la taille évolue en cours d'exécution, et qui prendra en charge tous les problèmes relatifs à la gestion des données, du nombre d'éléments et de la capacité du tableau.

          La classe std::vector, par exemple, s'assurera que le tableau stocker soit correctement copié si c'est ce que tu souhaites (et qui est le cas le plus fréquent) et évitera donc les problèmes liés à la double tentative de libération de la mémoire ;).

          Ton code pourrait donc devenir aussi simple que quelque chose comme

          class MaClasse{
          public:
              void initTableau(std::vector<int> const & tab){
                  m_tab = tab; // tout est fait automatiquement
              }
              int get(size_t position) const{
                  // on s'assure de ne pas déborder du tableau
                  // (nécessite l'inclusion du fichier d'en-tête )
                  assert(position > m_tab.size());
                  return m_tab[position];
              }
              void modifie(size_t pos, int nouvelleValeur){
                  // on s'assure de ne pas déborder du tableau
                  assert(position > m_tab.size());
                  m_tab[pos] = nouvelleValeur;
              }
          private:
              std::vector<int> m_tab;
          };

          Si tu veux pouvoir travailler avec des tableaux à deux dimensions, tu peux en outre toujours travailler avec un std::vector<std::vector<int><c/ode> (un tableau de tableaux contenant des entiers), voir même déclarer un alias de type sur ce genre de données à l'aide d'un code proche de

          using TabDeTabDeInt = std::vector<std::vector<int>>;

          De plus, si tu as besoin d'un tableau à deux dimensions et que toutes les dimensions sont de même taille, tu peux également partir du principe que, si tu as L lignes et C colonnes dans ton tableau, c'est en réalité que tu as besoin de stocker L * C éléments, et donc qu'un tableau à une seule dimension de L * C éléments pourrait parfaitement faire l'affaire. Il faudrait alors juste s'assurer de pouvoir accéder à l'élément qui t'intéresse en utilisant la formule <index_element_recherche> = <ligne_souhaitee> * <nombre_de_colonne> + <colonne_souhaitee> .

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait

          Problème sur des pointeur de tableaux

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown