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++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    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 : 62
    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
    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 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    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 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
    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.

  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 : 62
    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
    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 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    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 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    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
    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
    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++.

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

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 084
    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.

+ 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