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++Builder Discussion :

delete[] plante mon appli !


Sujet :

C++Builder

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 62
    Points : 46
    Points
    46
    Par défaut delete[] plante mon appli !
    Bonjour,

    j'en ai déjà parlé dans un autre post, mais je reprend pour ceux qui n'ont pas suivi

    Dans mon appli j'ai créé une classe pour gérer un formulaire Question-Réponse.
    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
    dans le .h
    class TFormulaire
    {
    private :
     
    TGroupBox *Boite;
    TEdit     *Reponse;
    TLabel    *Question, *Resultat;
     
     
    public :
            __fastcall TFormulaire(int Indice);
     
    };
     
    dans le .cpp
    __fastcall TFormulaire::TFormulaire(int Indice)
    {
        Boite    = new TGroupBox(MDIQForm);
        Reponse  = new TEdit(Boite);
        Question = new TLabel(Boite);
        Resultat = new TLabel(Boite);
        .../...
    }
    Bien sûr j'ai d'autre membres et fonctions mais qui ne sont pas concernés par le pb du moment.

    Dans ma fiche (c'est une fiche fille MDI mais je ne pense pas que cela change grand chose) MDIQForm.h j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TFormulaire *tabFormulaire[50];
    et pour créer une nouvelle ligne de mon formulaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tabFormulaire[i] = new TFormulaire(i);
    Jusque là, tout va bien.

    Mon pb est de deleter un ou tous les éléments mon tableau tabFormulaire[].
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delete[] tabFormulaire;
    me plante l'appli (Acces violation at address xxxx in module CC3260MT.DLL)
    Il n'y a pas de pb en revanche quand je fermer ma fiche.

    Est-ce parce que le Owner de ma TGroupeBox est la fiche elle-même ? Et dans ce cas que dois-je mettre à la place ?
    A moins que je ne fasse une autre erreur ......

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Ce qui est alloué dynamquement, ce sont les éléments de ton tableau, pas le tableau. Ce qu'il faut détruire via delete, ce sont donc les éléments et pas le tableau.

  3. #3
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Tu peux aussi dériver de TComponent !
    A mon avis... c'est plus simple et ça ne va pas prendre toute la mémoire !
    La destruction des TComponent s'opère automatiquement lors de la
    destruction de leur propriétaire !

    Donc et par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class TFormulaire : public TComponent 
    { 
    private : 
     
    TGroupBox *Boite; 
    TEdit     *Reponse; 
    TLabel    *Question, *Resultat; 
     
     
    public : 
            __fastcall TFormulaire(TComponent *Owner, int Indice); 
     
    };
    Son constructeur devient alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    __fastcall TFormulaire::TFormulaire(TComponent *Owner, int Indice)
        : TComponent (Owner)
    {
    Boite = new TGroupBox(this);
    Reponse = new TEdit(this);
    Question = new TLabel(this);
    if(Owner->InheritsFrom(__classid(TWinControl))) 
        {
        TWinControl *P = (TWinControl*)Owner
        Boite->Parent = P;
        Reponse->Parent = P;
        Question->Parent = P;
        }
    }
    La création des objets TFormulaire reste simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TFormulaire *Formulaires[50];
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    TFormulaire *F;
    for(int j = 0; j < 50; j++)
        {
        F = new TFormulaire(this, j); //les objets se dessineront sur this si this dérive de TWinControl
        Formulaires[j] = F;
        F->SetBounds(..,..,..,..); //positionnement à l'écran;
        }
    A plus !

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 62
    Points : 46
    Points
    46
    Par défaut
    Merci,

    1 - Pour loulou24 : j'ai déjà essayé de faire delete tabFormulaire[i]; mais ça ne donne pas non plus le résultat escompté Les objets ne sont plus accessibles via le programme, mais ma Boite reste affichée et fonctionnelle sur ma forme .....

    2 - henderson, je test ta solution ce soir.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 26
    Points : 29
    Points
    29
    Par défaut
    Lorsque tu fais un delete[], tu supprimes le tableau, pas les éléments que tu as créé dynamiquement par des new dans ton constructeur de classe.
    Très simplement, il te suffit de rajouter à ta classe un destructeur, et d'y incorporer les delete correspondants aux objets que tu as créé :


    __fastcall TFormulaire::~TFormulaire()
    {
    delete Boite;
    delete Reponse;
    etc...
    }

    Bien sûr, iul faut aussi penser à déclarer le destructeur dans le .h
    virtual __fastcall ~TFormulaire();

    Enfin, pourquoi ne pas plutôt utiliser une TList sur des pointeurs de tes formulaires, plutôt qu'un tableau statique très contraignant?

  6. #6
    Membre actif
    Avatar de Djob
    Inscrit en
    Août 2002
    Messages
    215
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 215
    Points : 279
    Points
    279
    Par défaut
    oui en effet,
    il faut faire un destructeur pour ta classe;

    cependant comme tu as des objets VCL dans ta classe :
    en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    __fastcall TFormulaire::~TFormulaire()
    {
     
    delete Boite
    delete Reponse ;///   <--- la, tu vas te taper un access violation
    }

    car si j'ai bien compris,
    Reponse est inclue dans Boite ...
    donc quand tu delete Boite , Boite va déjà détruire les composants à l'intérieur , mais bon pour en être sûr,

    écrit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    __fastcall TFormulaire::~TFormulaire()
    {
       Boite->DestroyComponents();   //<--force la destruction des composants qui appartiennent à Boite
       delete Boite;
    }
    ou alors fini par boite:

    delete ....
    delete ....
    delete Boite


    NB : avis perso , la méthode d'henderson me parait la plus propre ...

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 62
    Points : 46
    Points
    46
    Par défaut
    Merci à tous, ça fonctionne

    En fait j'ai pioché un peu dans toutes vos propositions.
    Comme le propose henderson, j'ai dérivé ma classe de TComponent mais cela ne résoud pas tout car j'avais encore le pb (ou alors j'ai pas tout bien fait ....) quand je voulais deleter un element du tableau.
    J'ai donc ajouter le destructeur (mais pourquoi n'y avais-je pas pensé plus tôt ?) dans lequel il suffit de deleter la Boite qui se charge de deleter les composants inclus.
    Et pour que personne ne soit en reste, j'ai remplacé mon tableau par une TList 8)

    Voila encore merci à tous

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Sur le coup ça m'a complètement échappé, mais en fait, il y a plus simple
    en dérivant de TGroupBox, puisque "Boite" est le parent des autres objets !
    L'exemple que j'ai donné est donc très éloigné de l'objet initial !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class TFormulaire : public TGroupBox 
    { 
    private : 
     
    TEdit     *Reponse; 
    TLabel    *Question, *Resultat; 
     
     
    public : 
            __fastcall TFormulaire(int Indice); 
     
    };
    A plus !

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 62
    Points : 46
    Points
    46
    Par défaut
    ok, merci c'est nickel en effet

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

Discussions similaires

  1. Conversion float/string plante mon appli
    Par chido dans le forum Android
    Réponses: 1
    Dernier message: 23/01/2015, 01h16
  2. [WD17] ReadDirectoryChangesW qui plante mon appli
    Par chapeau_melon dans le forum WinDev
    Réponses: 1
    Dernier message: 09/11/2012, 18h01
  3. xmlDocPtr plante mon appli
    Par lrgtk dans le forum C
    Réponses: 5
    Dernier message: 14/01/2010, 17h43
  4. pourquoi ma boucle fait planté mon appli ?
    Par zerros dans le forum Windows Forms
    Réponses: 5
    Dernier message: 02/05/2009, 16h21
  5. CArray RemoveAll plante mon appli
    Par damdam78 dans le forum MFC
    Réponses: 5
    Dernier message: 10/09/2008, 11h46

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