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 :

Tableau dynamique : Initialisation et vérification


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut Tableau dynamique : Initialisation et vérification
    Bonjour,




    Je cherche à initialiser le plus vite possible un tableau mais :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int *tableau = NULL;
     
    int taille = 10;
     
    tableau = new int[taille];

    Avec ce code, les valeurs du tableau ne sont pas à zéro.


    Existe-t-il une autre solution que de l'initialiser avec une boucle ?

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i = 0 ; i < taille ; i++)
    {
        tableau[i] = 0;
    }




    Et peut-on utiliser la même vérification qu'en C pour prévoir l'échec ?

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (tableau == NULL) 
    {
        cout << "Memoire insuffisante" << endl;
        delete[] tableau;
     
        system("pause");
    }

  2. #2
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    Existe-t-il une autre solution que de l'initialiser avec une boucle ?

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for (int i = 0 ; i < taille ; i++)
    {
        tableau[i] = 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include <algorithm>
     
    std::fill_n(tableau, taille, 0);
    std::fill(tableau, tableau+taille, 0);
    Note qu'on aura tendance à utiliser des std::vector plutôt que ce genre de tableaux.

    Et peut-on utiliser la même vérification qu'en C pour prévoir l'échec ?
    Si new échoue, il y a une exception qui est lancée.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    Quelle différence entre std::fill_n() et std::fill() ?


    Si new échoue, il y a une exception qui est lancée.
    C'est-à-dire ? comment je fais pour lancer le message d'erreur à l'utilisateur ?

  4. #4
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    Quelle différence entre std::fill_n() et std::fill() ?
    Les arguments. fill_n prend un nombre, fill un itérateur de fin.

    C'est-à-dire ? comment je fais pour lancer le message d'erreur à l'utilisateur ?
    Tu apprends à te servir des exceptions.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    En langage humain, je comprends que fill modifie les valeurs du tableau en une fois et fill_n revient à utiliser une boucle.


    Et concrètement, je ne vois pas comment on fait avec une exception, quant à l'explication sur la FAQ, ça fait plus m'embrouiller que m'aider.



    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (tableau == NULL) 
    {
        cout << "Memoire insuffisante" << endl;
        delete[] tableau;
     
        system("pause");
    }
    Ce code là est donc inutile ?


    Mon programme plante et j'ai exclu la possibilité que ça vienne d'une mauvaise allocation mais si cette condition ne sert à rien alors je ne peux plus m'y fier et j'en suis heureux...

    Tellement heureux que je devrais buter le chien du voisin pour calmer ma joie, je crois bien.

  6. #6
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    En langage humain, je comprends que fill modifie les valeurs du tableau en une fois et fill_n revient à utiliser une boucle.
    Les deux reviennent plus ou moins à utiliser une boucle.

    Et concrètement, je ne vois pas comment on fait avec une exception, quant à l'explication sur la FAQ, ça fait plus m'embrouiller que m'aider.
    La FAQ n'est pas un cours ni un bouquin destiné aux débutants.

    Ce code là est donc inutile ?
    new ne retourne jamais NULL.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Les deux reviennent plus ou moins à utiliser une boucle.
    Il vaut mieux la boucle si je ne veux pas un programme alourdi d'une bibliothèque de plus, si j'ai bien compris.


    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    new ne retourne jamais NULL.
    Il retourner quoi en cas d'échec ? pour que je puisse identifier cette erreur...

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    Il retourner quoi en cas d'échec ? pour que je puisse identifier cette erreur...
    Une exception.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    Et quelles lignes je dois écrire pour capturer cette exception dans une variable ?

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    La question étant: si tu n'arrives pas à allouer ton tableau, est-ce que continuer l'exécution de ton programme a encore un sens?

    Il vaut mieux la boucle si je ne veux pas un programme alourdi d'une bibliothèque de plus, si j'ai bien compris.
    euh. hein? Tout le code que tu vois qui commence par std:: fait partie du langage C++ à part entière, ça n'alourdi rien au contraire ça simplifie.

    sinon une exception ça se rattrape comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    try
    {
       // code qui peut lever une exception
    }
    catch( const std::exception & e )
    {
    // récupère les exceptions qui héritent de std::exception
        std::cerr << "exception: " << e.what() << std::endl;
    }
    catch( ... )
    {
    //récupère n'importe quelle exception
    }
    tu peux spécialiser les catchs suivant le type de l'exception. Un new qui échoue doit renvoyer un std::bad_alloc (sauf compilateur ne suivant pas la norme), tu peux décider d'attraper celle là spécifiquement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    catch( const std::bad_alloc & e )
    {
    }

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    La vache, ça me semble être un autre langage.


    Je crois que je vais revenir au malloc du C, en espérant qu'il soit compatible avec le C++...




    En tout cas merci, les experts !

  12. #12
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    Je crois que je vais revenir au malloc du C, en espérant qu'il soit compatible avec le C++...
    Malloc est fait pour être utilisé avec la partie "compatible" C du C++, le C++ ne connait que "new"

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    Mais c'est pas grave, non ?


    J'ai déjà vu des « rétro commandes » dans des codes.

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    Mais c'est pas grave, non ?


    J'ai déjà vu des « rétro commandes » dans des codes.
    Si tu fais du C non. Mais si tu fais du C, pourquoi vouloir faire du C en C++ et pas du C en C?

    En C++ on utilise des objets aussi. Et ça le malloc/free ne connaissent pas ( pas d'appel au constructeur ni au destructeur de l'objet )

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 112
    Points : 44
    Points
    44
    Par défaut
    C'est comme quand tu retiens pas un mot dans une langue étrangère, tu utilises le mot de ta langue natale, tu perds pas de temps.

  16. #16
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 174
    Points
    1 174
    Par défaut
    Citation Envoyé par Nikolas Voir le message
    C'est comme quand tu retiens pas un mot dans une langue étrangère, tu utilises le mot de ta langue natale, tu perds pas de temps.
    crois moi, ça va pas t'aider

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 627
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Si on a réellement un conseil à te donner, c'est de veiller à utiliser les possibilités du C++ tant que tu peux le faire (ou, à l'inverse, d'éviter d'utiliser les possibilités du C s'il existe un équivalent plus propre et plus sécurisant en C++).

    L'idée de mélanger le C et le C++ est en effet la pire que tu puisse avoir:

    Le plus souvent, cela t'incitera à réinventer la roue, et à refaire (qui a dit mal ) ce que d'autres ont déjà fait de manière bien plus sécurisée et vérifiée.

    Ainsi, il est une série d'habitudes prises en C qu'il est urgent d'oublier quand on débute en C++.

    Parmi celles ci, on peut citer:
    • L'utilisation de char* ou de char[] pour représenter les chaines de caractères (leur préférer l'utilisation de la classe std::string)
    • L'utilisation de l'allocation dynamique quand ce n'est pas absolument nécessaire (lui préférer les différents conteneurs existants)
    • Le passage systématique d'un pointeur comme argument à une fonction dans laquelle les modifications apportées doivent persister après la fonction (leur préférer les références)
    • utiliser malloc et free au lieu de new et delete
    • utiliser les fonctions *scanf, *sprintf, str* ...
    • surement une ou deux habitudes oubliées

  18. #18
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut, ça peut paraître terrible de ne pas pouvoir tout initialiser à 0, mais en C on ne peut pas le faire avec malloc (c'est avec calloc).

    Tu peux toujours utiliser le memcpy du C, si tu est sûr de ne pas faire d'erreurs, notamment au niveau de la taille.

    Note que ce problème ne se pose qu'au niveau des int: Quand tu fais tes propres structures/classes, tu peux choisir de les initialiser comme tu veux.
    new n'est ici peut-être pas le meilleur choix, mais quand il s'agit d'initialiser ses propres classes/structures, ça l'est

  19. #19
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Avec new T(), T est toujours value-initialized...
    Donc y'a pas d'initialisation à faire.

    (Remarque: avec GCC, new T value-initialize aussi)

Discussions similaires

  1. Réponses: 7
    Dernier message: 24/11/2011, 10h41
  2. Initialisation d'un tableau dynamique
    Par TheBombadil dans le forum Débuter
    Réponses: 2
    Dernier message: 13/11/2010, 11h44
  3. initialisation tableau dynamique
    Par mikew75 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 17/11/2008, 13h06
  4. [Tableau] Initialisation d'un tableau dynamique
    Par Rayek dans le forum Langage
    Réponses: 4
    Dernier message: 28/11/2007, 08h24
  5. Initialisation tableau dynamique
    Par exyacc dans le forum Delphi
    Réponses: 16
    Dernier message: 18/06/2007, 11h57

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