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 :

Malloc et Structure


Sujet :

C++

  1. #1
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut Malloc et Structure
    Bonjour

    Je voudrais creer pointeur sur un tableau de type Arme, Arme etant une structure definie.
    Je dois mal m'y prendre, car je compile sans warning ni error mais lorsque je lance le programme, cela plante.
    J'ai un SIGSEV , segmentation fault, mais je dois avouer que je ne vois pas ou.

    Voici Arme.h
    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
     
    #ifndef ARME_H
    #define ARME_H
     
     
    typedef enum NomArme
    {
        LANCE_ROQUETTE,
        LANCE_MISSILE,
        UF_45,
        RAPTOR,
        NombreArme = 4
    };
     
    typedef struct DefinitionArme
    {
     
        /* Caracteristique fixe de l'arme */
        std::string nom;
        float cadence;
     
    }Arme, *pArme;
     
    pArme CreationListeArmes (void);
     
    #endif

    et voici Arme.cpp
    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
     
    #include "arme.h"
     
    using namespace std;
     
    pArme CreationListeArmes (void)
    {
        pArme ListeArme = (pArme) malloc (sizeof(Arme) * NombreArme);
     
        /* On creer toutes les armes */
        ListeArme[LANCE_ROQUETTE].nom = "Lance Roquette";
        ListeArme[LANCE_ROQUETTE].cadence = 80;
     
        ListeArme[LANCE_MISSILE].nom = "Lance Missile";
        ListeArme[LANCE_MISSILE].cadence = 20;
     
        ListeArme[UF_45].nom = "UF 45";
        ListeArme[UF_45].cadence = 990;
     
        ListeArme[RAPTOR].nom = "Raptor";
        ListeArme[RAPTOR].cadence = 678;
     
        return ListeArme;
    }
    L'appel dans le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pArme ListeArme = CreationListeArmes();


    Je voudrais savoir ce qui ne va pas, car j'y bloque depuis pas mal de temps et j'avoue mon incompréhension devant ce probleme.

    J'ai donc quelques questions :

    1 - Le sigsev ne viendrait-il pas du fait que j'utilise des enum pour mon tableau ?
    2 - Est ce que j'ai réellement créer un pointeur vers un tableau de type Arme ?
    3 - Dans ma fonction, ne faudrait-il pas plutot faire
    ListeArme[LANCE_ROQUETTE]->nom = "Lance Roquette"; et non ListeArme[LANCE_ROQUETTE].nom = "Lance Roquette"; ?

    Voila, merci de m'avoir lu, bonne journée a vous.

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    2 choses

    Ton bug, comme tu fais un malloc, le constructeur de std::string nom de ta classe arme n'est pas appelé. Je pense que le string est dans un état "pâteux".

    Il ne faut pas mélanger le C et le C++ (et d'ailleurs, je vais déplacer ton post dans C++)

    Secondo, ton énumération me parait dangeureuse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef enum NomArme
    {
        LANCE_ROQUETTE,
        LANCE_MISSILE,
        UF_45,
        RAPTOR,
        NombreArme = 4
    };
    Lorsque tu vas vouloir rajouter une arme, il faudra pas oublier de modifier le "= 4" en "= 5" (et je parie que tu vas oublier).
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Salut,

    Merci de ta reponse


    Secondo, ton énumération me parait dangeureuse

    Code :

    typedef enum NomArme
    {
    LANCE_ROQUETTE,
    LANCE_MISSILE,
    UF_45,
    RAPTOR,
    NombreArme = 4
    };

    Lorsque tu vas vouloir rajouter une arme, il faudra pas oublier de modifier le "= 4" en "= 5" (et je parie que tu vas oublier).
    Non, justement.
    J'ai mis cette variable expres afin que plus tard, lorsque je rajouterai une arme, j'aurai juste a modifier cette enum.
    Enfin, si tu as plus securisé, je suis preneur.



    Il ne faut pas mélanger le C et le C++
    Euh, cela veut dire que l'on ne doit pas utiliser des structure avec le C++ ?
    Je viens de me rendre compte que j'utilise encore le malloc au lieu du new, mais mis a part cela, quelle instruction "appartienne" au C ?


    Ton bug, comme tu fais un malloc, le constructeur de std::string nom de ta classe arme n'est pas appelé. Je pense que le string est dans un état "pâteux".
    Ah, ca je ne le savais pas. J'avais lu qu'avec l'objet string, il suffisait juste de faire Arme.nom = "bonjour"; et que cela suffirait.
    Apparement non.
    Peut-tu m'en dire plus ? (La reference a l'etat "pateux" m'interesse).

    PS : Désolé, je me suis effectivement trompé de forum

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Pour l'utilisation du C il faisait référence au malloc surtout je pense. En effet le malloc n'appelle pas le constructeur et donc les objets ne sont pas initialisés.
    Deux autres choses qui te viennent certainement du C :
    Les casts C-like t'oublies à la place utilise des casts du C++ qui sont beaucoup plus safe (les casts en x_cast<> comme static_cast<> dynamic_cast<> etc).
    La définition des structures / classe en C++ pas besoin de typedef :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    typedef struct foo{
    } foo;
    s'écrit tout simplement en C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    struct foo{};
    //plus loin dans le code pour créer une instance :
    foo x;

    Enfin ici tu n'as pas besoin d'un pointeur, (enfin pas avec le code que tu nous montre) et donc t'embêter avec de l'alloc dynamique. alloue tout ça statiquement sur la pile.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    1/ Pas besoin de mettre =4 ou =5 derrière NombreArme, le compilateur le fait sans erreur donc laisse le faire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef enum NomArme
    {
    LANCE_ROQUETTE,
    LANCE_MISSILE,
    UF_45,
    RAPTOR,
    NombreArme     /* doit IMPERATIVEMENT être le dernier item de l'numeration */
    };
    2/ Si si, on peut utiliser des structures en C++ mais quand ces structure contiennent des objets au sens C++ du terme, il faut les allouer avec new et surtout pas malloc.

    3/ malloc() appartient au C (comme printf et scanf) et new appartient au C++ (comme std::cin et std::cout)

    4/ Quand tu fais un new d'une structure contenant des objets C++ (std::string dans ton cas), les constructeurs de ces objets sont automatiquement appelés par new.

    Dans ton cas, tu faisais un malloc et donc le constructeur de std::string n'était pas appelé (par contre il avait sa place réservée). Comme le constructeur n'est pas appelé, le std::string n'est pas initialisé et contient donc des valeurs aléatoires.

    Lorsque tu faisait ensuite std::string nom = "roquette", le std::string devait essayer de libérer son buffer interne ou croire qu'il était initialisé et cela partait en cacahuète
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Argh

    Chuis deg'

    Bon, merci de vos précision, je test tout ca et je vous tient au courant.

    Difficile de passer au C++ quand on a trop d'automatisme du C

  7. #7
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Bon, ben tout roule.
    Merci a vous

    Je vais revoir les base du C++, notamment les structures. Je ne savait pas qu'il y avait une difference entre le C et le C++ pour les cast.

    Je met le post en resolu, of course

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par SofEvans Voir le message
    Bon, ben tout roule.
    Merci a vous

    Je vais revoir les base du C++, notamment les structures. Je ne savait pas qu'il y avait une difference entre le C et le C++ pour les cast.

    Je met le post en resolu, of course
    Le fait est surtout que C te fait entièrement confiance lorsque tu décide de transtyper un objet en un autre:

    Il lui est en effet impossible de déterminer si tu ne fais pas une boulette en effectuant le transtypage et que tu n'essaye donc pas de faire passer un éléphant pour une cacahuète

    De plus, la syntaxe utilisée pour le transtypage ( parenthèse ouvrante + type parenthèse + fermante) est à ce point commune ( on place tant de choses entre parenthèses) qu'il devient difficile de séparer, parmi tout ce qui se trouve entre parenthèses ce qui est un transtypage de ce qui est autre chose.

    Les *_cast<type> du C++ résolvent ces deux problèmes, dans le sens où chaque transtypage aura un résultat bien déterminé, et où le terme même utilisé permet de se rendre compte rapidement à la lecture que l'on effectue un transtypage.

    Dans le cas présent, malloc() renvoyant un pointeur sur void et ce type de pointeur ne pouvant décidément pas passer pour un pointeur sur un type différent en C++, il faudrait utiliser reinterpret_cast qui aura le même résultat que le transtypage "C style", mais qui est bien plus facile à repérer dans le code

    Mais, comme l'a fait valoir ram-0000, malloc se contente d'allouer la mémoire nécessaire pour représenter un objet, sans appeler le constructeur de cet objet.

    Le résultat est que tu ne peux absolument pas savoir quelles seront les valeurs données aux différents membres de cet objet (et au membre des structures utilisées comme membre de cet objet, et ainsi de suite), parce qu'elles seront représentées par... les "crasses" laissées par une utilisation antérieure de la mémoire.

    C'est pour ces deux raisons qu'il est préférable d'utiliser l'opérateur new (ou new[]).

    En effet, dans un contexte d'héritage (et nous pourrions envisager de créer une arborescence d'armes par héritage dans laquelle nous aurions le type "générique" Arme et un certain nombres d'armes particulière comme FusilaLunette, Carabine, LanceRoquette, Mitrailleuse, Canon,... qui héritent de Arme) et de polymorphisme, nous serions en mesure de créer une arme particulière (par exemple Mitrailleuse) et de la faire passer pour... une arme (tout à fait générique) avec une syntaxe proche de
    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
    Arme *parme=new Mitrailleuse(/*paramettres éventuels */);
    /* nous utilisons notre mitrailleuse au travers de l'interface publique de Arme 
     * comme 
     */
    parme->shoot(); /* on tire */
    parme->reload(); /* on recharge */
    parme->changeCadence(); /* on passe du tire en rafale au tir unique 
                             * et inversement (pour les armes le supportant) 
                             */
    parme->shoot();  /* on tire encore */
    /* voir, s'il existe des fonctions libres shoot, reload et
     * changeCadence (prenant chaque fois comme parametre un pointeur
     * sur l'arme utilisée) 
     */ 
    shoot(parme);
    reload(parme);
    changeCadence(parme);
    shoot(parme);
    Mais tu n'a visiblement pas considéré la possibilité de créer une telle hiérarchie d'armes, et ton idée est, vraisemblablement, de créer en fait un tableau d'armes.

    L'idéal serait alors de travailler avec les conteneurs de la STL, de manière à t'éviter les problèmes liés à la gestion dynamique de la mémoire.

    Ta fonction CreationListeArmes prendrait alors idéalement la forme de
    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
    std::vector<DefinitionArme> CreationListeArmes (void)
    {
        std::vector<DefinitionArme> ListeArme(NombreArme);
        /* On creer toutes les armes */
        ListeArme[LANCE_ROQUETTE].nom = "Lance Roquette";
        ListeArme[LANCE_ROQUETTE].cadence = 80;
     
        ListeArme[LANCE_MISSILE].nom = "Lance Missile";
        ListeArme[LANCE_MISSILE].cadence = 20;
     
        ListeArme[UF_45].nom = "UF 45";
        ListeArme[UF_45].cadence = 990;    
     
        ListeArme[RAPTOR].nom = "Raptor";
        ListeArme[RAPTOR].cadence = 678;
     
        return ListeArme;
    };
    et la fonction qui manipule les armes pourrait n'être modifiée que pour utiliser... un
    std::vecto<DefinitionArme> au lieu d'un DefinitionArme* sous la forme de
    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
    void foo()
    {
        std::vector<DefinitionArme> WeaponsTab=CreationListeArmes();
        /* j'utilise le lance minssile (*)
         */
        shoot(WeaponsTab[LANCE_MISSILE]);
        /* puis j'utilise le raptor (*) 
         */
        shoot(WeaponsTab[RAPTOR]);
        /*...*/
        /* je n'ai même plus besoin de veiller à la libération de la mémoire
         * de WeaponsTab, qui sera détruit automatiquement lorsque
         * je quitte la fonction
         */
    }
    (*) Attention, pour que les modifications éventuellement apportée à l'arme lors du tir (comme la diminution du nombre de munitions dont tu dispose pour l'arme) soient prises en compte dans la fonction qui appelle shoot, l'arme doit être passée sous la forme d'une référence (non constante)
    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 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    1/ Pas besoin de mettre =4 ou =5 derrière NombreArme, le compilateur le fait sans erreur donc laisse le faire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef enum NomArme
    {
    LANCE_ROQUETTE,
    LANCE_MISSILE,
    UF_45,
    RAPTOR,
    NombreArme     /* doit IMPERATIVEMENT être le dernier item de l'numeration */
    };
    Il m'arrive de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    enum NomArme
    {
    LANCE_ROQUETTE =0,
    LANCE_MISSILE,
    UF_45,
    RAPTOR,
    NombreArme
    };
    Et le typedef n'est pas nécessaire en C++.

  10. #10
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Merci pour vos information.

    J'ai effectivement lu que les vector seraient indiqué en C++ et qu'il ne faut plus faire de tableau alloué dynamiquement, meme avec new.

    Quelles seraient les consequence d'un new sur un tableau ?

    Au fait, j'utilise le typedef car il permet de faire un alias avec un pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct DefinitionArme
    {
    /* Code */
    }Arme, *pArme;
    Ainsi, il me suffit de faire pArme au lieu de *Arme.
    Quel est l'equivalent en C++ ?



    Merci aussi pour l'explication du transtypage, je vais approfondir davantage cela.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par SofEvans Voir le message
    Merci pour vos information.

    J'ai effectivement lu que les vector seraient indiqué en C++ et qu'il ne faut plus faire de tableau alloué dynamiquement, meme avec new.
    Le fait est qu'il vaut mieux éviter d'avoir recours à l'allocation dynamique effectuée par soi-même chaque fois qu'elle n'est pas absolument indispensable, ne serait-ce que parce qu'elle implique que tu prend la responsabilité de la durée de vie de l'objet créé dynamiquement.

    Il est donc très facile, si tu ne fais pas suffisamment attention à ce que tu fais, d'arriver soit à des fuites mémoires (tu "perds" l'adresse d'une variable créée dynamiquement avant d'avoir pu... libérer la mémoire par le delete approprié), soit à des tentatives de double libération de la mémoire (ce qui arrive principalement si tu utilise un pointeur dans une structure pour laquelle tu ne redéfinis pas le constructeur par copie et l'opérateur d'affectation).

    C'est d'ailleurs la raison pour laquelle nous insistons beaucoup sur le fait que, si tu es vraiment face à la nécessité d'utiliser l'allocation dynamique, il est largement préférable d'avoir recours aux pointeurs intelligent ("smart pointers") voir d'utiliser les boost::ptr_container's qui fonctionnent comme les containers équivalents de la STL, mais qui invoquent explicitement l'opérateur delete sur leur contenu
    Quelles seraient les consequence d'un new sur un tableau ?
    Je présumes que tu veux parler d'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<int> *ptrTab =new std::vector<int>;
    En toute honnêteté, aucune, du moins, du point de vue des performances(si ce n'est que l'ensemble de l'instance ptrTab se trouvera dans le tas et non dans la pile)...

    Cependant, comme toute variable pour laquelle tu peux avoir recours à l'allocation dynamique, tu prend sur toi la responsabiltié de la gestion de la durée de vie de l'objet.

    C'est à dire qu'il te revient de décider du moment opportun auquel il faudra libérer la mémoire, et que tu cours donc encore une fois le risque d'obtenir soit une fuite mémoire soit une double libération de la mémoire.

    En l'espèce, ce sera d'autant plus embêtant que l'un des membres des différents conteneurs de la STL n'est autre... qu'un pointeur pointant vers une adresse mémoire allouée dynamiquement et libérée par le destructeur du constructeur, qui ne sera appelé que lors de l'invocation de delete...

    Si tu ne prévois pas d'invoquer delete sur ptrTab (selon l'exemple) au moment adéquat, la fuite mémoire sera donc d'autant plus importante qu'il y aura un nombre élevé d'éléments

    Au final, il est généralement bien plus intéressant de créer des instances des différents conteneurs de la STL sous forme de valeur (par opposition au fait de les créer sous forme de pointeurs) et de les passer en paramètre sous forme de référence (constante ou non selon le cas).

    Si le conteneur est un membre de classe et que tu dois (mais il est rarement vraiment intéressant de le faire) renvoyer le conteneur, il est préférable de le renvoyer par référence (et, afin d'éviter une modification "indue" de son contenu, je dirais même sous forme d'une référence constante)
    Au fait, j'utilise le typedef car il permet de faire un alias avec un pointeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    typedef struct DefinitionArme
    {
    /* Code */
    }Arme, *pArme;
    Ainsi, il me suffit de faire pArme au lieu de *Arme.
    Quel est l'equivalent en C++ ?
    Je ne suis personnellement pas partisan du fait de cacher un pointeur par un alias de type, que ce soit en C ou en C++...

    Finalement, je ne trouve pas vraiment plus difficile d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type * myPtr = new Type;
    plutôt que d'écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TypePtr myPtr = new Type;
    et ce d'autant plus qu'il est très facile, dans le second exemple, de croire suite à une lecture un peu trop en diagonale que Type et TypePtr sont deux types différents, faisant partie d'une hiérarchie de classe commune dans laquelle TypePTr serait une classe de base de Type, ce qui n'est pas le cas.

    Cependant, rien ne t'empêche (si vraiment tu veux avoir un alias de type sur le pointeur d'une structure) d'envisager un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* En C++, la définition d'une classe, d'une structure, d'un énumération
     * ou d'une union provoque automatiquement la définition du type
     * associé
     */
    struct MaStruct
    {
        /*...*/
    };
    typedef MyStruct* PtrStruct;
    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

  12. #12
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Merci pour cette reponse tres detaillé Koala01.

    Je vais devoir regarder un peu partout car je ne connait pas tout les termes, ni toutes les notions basiques.

    /* En C++, la définition d'une classe, d'une structure, d'un énumération
    * ou d'une union provoque automatiquement la définition du type
    * associé
    */
    struct MaStruct
    {
    /*...*/
    };
    typedef MyStruct* PtrStruct;
    Dans cet exemple, ce ne serai pas plutot :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef MaStruct* PtrStruct;
    Excuser moi si je pinaille, mais cela me trouble un peu.

    Merci de toute vos explication.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Oui c'est bien maStruct.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  14. #14
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Merci de vos reponse.

    J'ai bien compris ce qu'il n'allait pas et j'ai des piste pour continuer.


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

Discussions similaires

  1. Problème de malloc sur structures.
    Par Mornor dans le forum Débuter
    Réponses: 8
    Dernier message: 09/05/2013, 18h01
  2. Réponses: 6
    Dernier message: 12/04/2007, 13h58
  3. structure imbriquée malloc problème
    Par tuxout dans le forum C
    Réponses: 3
    Dernier message: 26/02/2007, 06h49
  4. Réponses: 6
    Dernier message: 15/12/2006, 13h55
  5. Malloc / structures imbriquées
    Par Lolita59 dans le forum C
    Réponses: 14
    Dernier message: 11/05/2006, 15h43

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