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 :

Structure de donnée et tableaux


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Par défaut Structure de donnée et tableaux
    Bonjour !

    Pour commencer, je suis novice en C++, j'ai lu des cours en C mais n'ai jamais tenu de réel projet, manque d'idée. Cependant, ayant assez de connaissances en C, je me suis intéressé au C++ près d'un an après et me voici aux structures de données.

    J'ai un lèger souci avec ce 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <iostream>
    #include <string>
    using namespace std;
     
    struct foo{
      string x;
      string y;
    } *pointer;
     
    int main ()
    {
      short i, a;
     
      cout << "Longueur du tableaux : ";
      cin >> a;
      pointer = new foo [a];
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 1 array " << i << " : ";
        getline(cin, pointer[i].x);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 2 array " << i << " : ";
        getline(cin, pointer[i].y);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].x << endl;
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].y << endl;
      }
      return 0;
    }
    Comme vous pouvez le voir, je créer un objet pointer qui est donc un pointeur.

    Par la suite, je demande à l'utilisateur quelle taille doivent faire les tableaux de string pointer[].x et pointer[].y

    Ensuite on remplit les tableaux.
    Et on finit par afficher leur contenu.

    Seulement, voici ce que j'obtient en sortie, lors des tests:

    Entrez une phrase pour tableau 1 array 0 : Entrez une phrase pour tableau 1 array 1 : 0
    Entrez une phrase pour tableau 2 array 0 : 1
    Entrez une phrase pour tableau 2 array 1 : 2

    0
    1
    2

    Ce qui m'embête c'est qu je ne peux pas entrer quelquechose dans la première case du premier tableau...

    Merci d'avance.

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Essaye en purgeant le buffer clavier...

    ie comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    Juste après la lecture sur le cin.


    ps : ça implique d'inclure limits .

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Par défaut
    Edit: j'ai rien dit...

    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <iostream>
    #include <string>
    #include <limits>
     
    using namespace std;
     
    struct foo{
      string x;
      string y;
    } *pointer;
     
    int main ()
    {
      short i, a;
     
      cout << "Longueur du tableaux : ";
      cin >> a;
      pointer = new foo [a];
     
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 1 array " << i << " : ";
        getline(cin, pointer[i].x);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 2 array " << i << " : ";
        getline(cin, pointer[i].y);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].x << endl;
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].y << endl;
      }
      return 0;
    }
    Maintenant ça fonctionne.

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Ceci dit, l'utilisation de variables globales est généralement largement déconseillée... surtout si, en plus, il s'agit de pointeurs(parce que l'utilisation de pointeur est, elle aussi, fortement déconseillée :aie)

    Veux tu la preuve de ce que j'avance

    Sur un code qui ne fait que quelques lignes, tu arrive déjà a obtenir une fuite mémoire, simplement parce que tu as pensé à allouer correctement la mémoire pour ton pointeur, mais que tu n'a pensé nulle part à... libérer cette mémoire

    Et cela nous amène tout naturellement à l'exposé de la raison qui rend mon conseil si important:

    Déjà, chaque fonction est susceptible de modifier une variable globale...

    Tu ne peux donc pas partir de la moindre présomption concernant cette variable au moment où tu décid de la manipuler

    De plus, comme il s'agit d'un pointeur, toute fonction qui utilise la variable est susceptible:
    • de décider d'effectuer une allocation dynamique de l'objet, alors que ce n'est pas *forcément* nécessaire ni indiqué
    • de décider d'effectuer une libération de la mémoire, alors que ce n'est pas *forcément* nécessaire ni indiqué
    Le résultat, si l'une de ces situations survient sera, au mieux (dans le premier cas) une fuite mémoire, au pire (dans le second cas) une double libération de la mémoire).

    Au final, pour essayer de contourner ce type de problème, tu devra non seulement adopter une politique clairement défensive (consistant à vérifier en priorité et à tout moment si le pointeur est valide), mais aussi prendre des habitudes contraignantes de remise du pointeur à NULL chaque fois qu'une fonction libérera la mémoire allouée à la variable globale en question.

    Peut être pourrions nous t'indiquer la meilleure solution si tu nous disais dans quelle circonstances tu souhaite utiliser ta variable globale
    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

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Par défaut
    Ah... les variables globales. Je les avaient oubliées celle-là !
    C'est corrigé, je ne sais pas pourquoi le l'ai mise là tiens...

    A vrai dire, ce que j'ai codé c'était juste pour m'exercer avec la manipulation des structures additionnées de pointeurs...

    J'ai effectivement zapé la libération de mémoire !
    Dans le code je ne sais pas comment la libèrer... peux-tu m'aider ?

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    C'est un tableau, alloué par new[], donc un delete[] pointer; suffit.

    Après, dans du code réel, il faut utiliser std::vector à la place de ce genre d'horreur.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Par défaut
    vector ? Pourquoi l'utiliser et surtout à la place de quoi ? De l'allocation dynamique avec new ?

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par zebulondu54 Voir le message
    vector ? Pourquoi l'utiliser et surtout à la place de quoi ? De l'allocation dynamique avec new ?
    Si on part sur une allocation dynamique de la mémoire, effectivement, un std::vector semble largement plus intéressant à utiliser...

    Si le tableau ne doit jamais avoir qu'une taille clairement définie à l'avance et qu'il n'est pas nécessaire de la modifier au long de l'application, un tableau "C style" ou un boost::array peut faire l'affaire
    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

  9. #9
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Citation Envoyé par zebulondu54 Voir le message
    vector ? Pourquoi l'utiliser et surtout à la place de quoi ? De l'allocation dynamique avec new ?
    Plus de problème de gestion de la mémoire, enveloppe RAII sur tes données (comprendre que la destruction se fait automatiquement)
    Exemple:
    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
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    #include <iostream>
    #include <string>
    #include <vector>
    #include <limits>
     
    using namespace std;
     
    struct foo{
      string x;
      string y;
    };
     
    int main ()
    {
      short i, a;
     
      cout << "Longueur du tableaux : ";
      cin >> a;
      std::vector<foo> pointer(a); //ici on  réserve un tableau pour a objet, mais on pourrait en ajouter au fur et à mesure.
     
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 1 array " << i << " : ";
        getline(cin, pointer[i].x);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << "Entrez une phrase pour tableau 2 array " << i << " : ";
        getline(cin, pointer[i].y);
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].x << endl;
      }
     
      for(i = 0 ; i < a ; i++){
        cout << pointer[i].y << endl;
      }
      return 0;
    }
    Les vectors, c'est bon, il faut en manger (et la STl en général) car ca offrent plein de possibilité. Ajout d'élement simplifié, accès à la taille de la collection,...

    Recherche sur google et une fois que tu y as gouté, tu ne t'en passes plus.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par fcharton Voir le message
    C'est peut être pas la caractéristique que je mettrais en premier, ça...
    Ce que je mettrais en premier, c'est en fait le RAII (et l'explication qui va avec )
    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

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7
    Par défaut
    Ulaa... je crois que je vais finir le tuto en C++ de cplusplus.com et après je reviendrais lire tout ce qui a été dit...

    Ma fois merci beaucoup ! Sachez que tout ce que vous avez dit ne sera pas perdu

  12. #12
    Membre très actif
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 432
    Par défaut
    Si je peux me permettre de scouater momentanément le topic pour poser une question :

    Quand vous dites qu'un std::vector garanti l'appel du destructeur c'est par rapport à un tableau style C dynamique ?

  13. #13
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Si je peux me permettre de scouater momentanément le topic pour poser une question :

    Quand vous dites qu'un std::vector garanti l'appel du destructeur c'est par rapport à un tableau style C dynamique ?
    Oui, et de manière générale une gestion "saine" de la mémoire allouée dynamiquement (et de manière transparente pour ce qui touche à la STL)
    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

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

Discussions similaires

  1. Structures de données, tableaux et enregistrements
    Par Lulu005 dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 03/01/2013, 13h40
  2. [Structure de donnée] plusieurs tableaux dans form
    Par [ced] dans le forum Struts 1
    Réponses: 5
    Dernier message: 27/10/2008, 09h26
  3. Méta-Programmation - [ structures de données ]
    Par Dam)rpgheaven dans le forum C++
    Réponses: 3
    Dernier message: 03/12/2004, 19h38
  4. Structure des données en retour d'un DBExtract ?
    Par mikouts dans le forum XMLRAD
    Réponses: 4
    Dernier message: 24/01/2003, 15h15
  5. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10

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