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 de struct


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Par défaut tableau dynamique de struct
    Hello les geeks :-),

    Je tente de créer un tableau dynamique de structure.
    Il est définit ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
         struct TFile
         {
             signed long Index;
             AnsiString Name;
             int Attribute;
         };
    Il est déclaré ainsi :


    Lorsque j'en modifie la dimension par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
         if ((Files=(TFile *)realloc(Files,Number*sizeof(TFile)))==NULL)
     
    // Number = le nombre de struct TFile dans le tableau Files
    il ne renvoie jamais de pointeur NULL mais crashe de temps en temps des TFile dans le tableau Files
    J'en déduis que mon allocation de mémoire est foireuse mais je ne comprends pas pourquoi.

    Merci de m'aider (et non, je ne suis pas tenté par std::vector, je voudrais plutôt comprendre que contourner le problème )

  2. #2
    Membre émérite

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Par défaut
    Ton code est un code C. En C++ on n'appelle jamais les fonction malloc(), realloc(), free(), etc. Si vraiment tu veux gérer des tableaux dynamiques toi-même fais-le avec new et delete, y compris pour la réallocation (il n'y a pas d'équivalent à realloc() en C++).

    (et non, je ne suis pas tenté par std::vector, je voudrais plutôt comprendre que contourner le problème )
    Ce n'est pas contourner le problème, juste utiliser la bibliothèque standard au même titre que toi tu utilises des fonctions comme realloc par exemple .

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 394
    Par défaut
    En plus, c'est du Borland (AnsiString, TFile...)

    PS Fiquet: Par "Il n'y a pas de realloc() en C++", tu viens d'expliquer pourquoi diFaenza emploie malloc(). realloc() est beaucoup plus économique que new/copy/delete, tant en performances qu'en efforts.

    Par contre diFaenza, realloc() est très mal utilisé:
    1. On ne doit jamais remettre directement la valeur de retour de realloc() dans le pointeur d'origine, car si realloc() retourne NULL le pointeur est toujours valide.
    2. Tu utilises des transtypages de type C au lieu d'utiliser static_cast<>().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    29
    Détails du profil
    Informations personnelles :
    Âge : 49

    Informations forums :
    Inscription : Octobre 2005
    Messages : 29
    Par défaut Et donc, si on fait new / delete
    Tout d'abord, où est le problème avec le Builder de Borland (il transmet des MST, le cholera ou il finance le terrorisme ? ;-) )

    Mais revenons à mes angoisses diurnes

    je garde
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct TFile
    {
         signed long Index;
         AnsiString Name;
         int Attribute;
    };
     
    TFile *Files;
    et je le newise avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Files= new TFile[Number];
    // Number = le nombre de Files dans mon tableau de Files
    Jusque là, no problemo, je joue avec et il hoche la queue.

    Mais lors du licenciement
    il fait son vilain et mord.

    Où est ma faute?


    balises [code] rajoutées par r0d. Merci d'y penser dorénavant.

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

    Informations professionnelles :
    Activité : aucun

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

    D'abord, il faut se ménager une "porte" de sortie quand tu utilises new (pas de réallocation possible, cela veut dire: garder l'ancien pointeur, copier les valeurs, et libérer l'ancien pointeur)

    Ton code doit donc etre du genre 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
    19
     
    // déclaration de Files (utilisé réellement)
    FTile *Files=NULL;
    (...)
    // création d'un nouveau tableau temporaire
    TFile *tempo;
    if(!(tempo=new TFile[nouvelle_taille]))
         throw std::bad_alloc("erreur d'allocation");
    /* si on a déjà un tableau de TFile, il faut le recopier dans le tableau temporaire */
    for(unsigned int i=0;i< ancienne_taille,i++)
    {
         tempo[i]->index=File[i]->Index;
         tempo[i]->Name=File[i]->Name;
         tempo[i]->Attribute=File[i]->Attribute;
    }
    // Maintenant, il faut libérer la mémoire réservée pour File 
    delete[] File;
    //Et donner a File l'adresse du tableau tempo
    File=tempo;
    Ceci dit, en espérant te convaincre... Ne trouverais tu pas plus simple un code basé sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    std::vector<TFile> Files;
    //Ajout d'un TFile
    File.push_back(lenouveau);
    //suppression d'apres l'index)
    std::vector<TFile>::iterator it=Files.begin()+index;
    Files.remove(it);
    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

  6. #6
    Invité
    Invité(e)
    Par défaut
    di Faenza, ouvre un peu ton esprit; on ne cherche pas a s'opposer a toi, ou te prend la main pour te ramener sur le droit chemin

    si tu codes en C++, alors utilise le jusqu'au bout. la bibliotheque standard n'est pas la pour que des intellectuels se possent des questions philosophique sur le bien fondé de son origine. la STL est rodée, elle marche bien, et est la justement pour éviter les fuites de mémoires si faciles à faire avec des allocations dynamiques manuelles...

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Citation Envoyé par diFaenza
    Je tente de créer un tableau dynamique de structure.
    Pas vraiment une structure au sens POD du terme. Ta struct contient une AnsiString qui est une classe. En conséquence ta struct est à 100% une classe et à 0% une donnée POD. De fait, tu ne peux pas allouer de TFile avec les fonctions de la famille *alloc du C. Tu oublies donc realloc au passage. Il ne faut pas chercher plus loin si ça plante.

    std::vector est LA solution du C++ à ce que tu cherches à faire.

    (En vrai, il est toujours possible de feinter avec les new de placement (ce que fait vector en interne), mais tu vas avoir d'autres bases à assimiler avant)



    Concernant la question suivante. Si tu plantes entre le new[] et le delete[], c'est que ton programme a fait le cochon sur la mémoire allouée entre ces deux lignes.





    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    FTile *Files=NULL;
    (...)
    // création d'un nouveau tableau temporaire
    TFile *tempo;
    if(!(tempo=new TFile[nouvelle_taille]))
         throw std::bad_alloc("erreur d'allocation");
    /* si on a déjà un tableau de TFile, il faut le recopier dans le tableau temporaire */
    for(unsigned int i=0;i< ancienne_taille,i++)
    {
         tempo[i]->index=File[i]->Index;
         tempo[i]->Name=File[i]->Name;
         tempo[i]->Attribute=File[i]->Attribute;
    }
    A moins que le BCB utilisé soit aussi à l'ouest que les vieux VC, new est sensé lever une exception par défaut. Pas null s'il n'y a plus de mémoire.
    Accessoirement, si l'affectation de l'AnsiString est refusée, une exception partira et de la mémoire sera perdue avec le code montré.
    Conclusion, c'est bien les vecteurs.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 19/03/2015, 18h31
  2. Double tableau dynamique de pointeurs de struct
    Par dedibox26 dans le forum Débuter
    Réponses: 2
    Dernier message: 27/04/2010, 15h24
  3. AFFICHER UN TABLEAU DYNAMIQUE
    Par ghassenus dans le forum Langage
    Réponses: 2
    Dernier message: 28/12/2002, 14h19
  4. [Kylix] tableau dynamique
    Par sdoura2 dans le forum EDI
    Réponses: 1
    Dernier message: 31/10/2002, 08h57
  5. Réponses: 4
    Dernier message: 13/05/2002, 16h43

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