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 :

[Méthode DestroyComponents() et access violation]


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut [Méthode DestroyComponents() et access violation]
    Bonjour,

    cette fois je vais essayer d'être clair et précis.
    J'utilise Borland C++ Builder 6.

    Je rencontre une erreur "d'access violation" quand j'utilise la méthode DestroyComponents();

    Voici mon code (simplifié)
    [code d'un bouton]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int decalage=0;
    for (int i=0;i<6;i++)
            {
            MonLabel=new TLabel(GroupBox1);
            MonLabel->Parent=GroupBox1;
            MonLabel->Top=15;
            MonLabel->Caption="exemple";
            MonLabel->Left=decalage;
            decalage=decalage+30;
            MonLabel->OnClick=MonLabelClick;
            }
    [code de MonLabelClick]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GroupBox1->DestroyComponents();
    Il me faut "vider" le GroupBox1 afin de créer dynamiquement de nouveaux labels.

    Et c'est là que je rencontre l'erreur d'access violation. Si je ne crée qu'un seul label, le problème ne se présente pas. Il s'agit d'un problème de mémoire apparemment.

    Puis-je contourner cette erreur d'une manière ou d'une autre ? Et comment ?

    Je n'ai jamais eu de cours en C++, certaines notions comme le "owner", un "constructeur" et un "destructeur" m'échappent encore.

    Par avance, merci.
    Nuclear.

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Bonjour,
    "access violation" signifie que tu libère, lis ou écrit dans de la mémoire qui ne t'appartient pas, c'est à dire, que tu n'as pas allouée

    Pour les notions, en version (un peu) courte:
    Le "owner", ou propriétaire, d'une ressource, est celui qui l'a acquise, et surtout, celui qui doit la libérer.
    C'est soit une classe, soit une fonction libre.
    Ton code est fiable si chaque fois qu'une ressource est acquise, elle possède (au moins) un propriétaire jusqu'à sa libération, et qu'elle est libérée aussitôt qu'elle n'as plus de de propriétaire.

    Typiquement, la fonction suivante est un monstre, parce que personne l'allocation de mémoire n'as plus de propriétaire une fois que la fonction a retournée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int& mauvaise_fonction(){
        return new int(1);
    };
    Le constructeur est une fonction (une méthode) chargée d'initialiser la mémoire fraichement allouée pour une valeur du type construit, et permet de plus d'effectuer certains controles initiaux.
    Supposons la structure suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    namespace base{
    struct Exemple {
        int a, b;
        explicit Exemple(int valeur);
    };
    }
    la fonction Exemple(int valeur), de son vrai nom explicit base::Exemple::Exemple(int valeur); est le constructeur.
    Je le défini ici comme explicite pour interdire la conversion automatique d'un int en Exemple (Exemple e = 2;).

    Tu peux avoir une implémentation telle que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    explicit base::Exemple::Exemple(int valeur) :
        a(valeur), b(-valeur) //liste d'initialisations des membres, pour les objets, ce sera un appel de constructeur
    {// corps du constructeur. les membres ont tous reçus une valeur (éventuellement par défaut)
        if(valeur==0) throw std::invalid_argument("le constructeur d'Exemple n'accepte pas la valeur 0");
    }
    Lever une exception dans un constructeur annule la construction de l'objet.

    Le destructeur permet de réaliser quelque chose (généralement, libérer des ressources) quand la variable disparait.
    Les deux usages (implicites et automatiques) sont :
    • appel à delete
    • sortie de la portée de définition d'une variable


    Voici un exemple simple de capsule de libération automatique, pour un pointeur vers un type arbitraire:
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <iostream>
    #include <stdexcept>
     
    template <typename T>
    class autoliberateur {
    private:
    	T * const pointeur;
    public:
    	autoliberateur(T* p) : pointeur(p) {
    		if(p==nullptr) throw std::invalid_argument("null pointeur?");
    	}
    	~autoliberateur() {
    		delete(pointeur);
    	}
     
    	T& operator*() const {
    		return *pointeur;
    	}
    };
     
    using namespace std;
    int main() {
    	{
    		int *pointeur = new int(1);
    		cout << *pointeur << endl;
    		//ne pas oublier de libérer le pointeur
    		delete(pointeur);
    	}//ici, pointeur devient hors de portée, étant d'un type primitif (int*), il est simplement oublié.
     
    	{
    		autoliberateur<int> al(new int(2));
    		cout << *al << endl;
    	}//ici, al devient hors de portée, étant d'un type objet, son destructeur est appelé, libérant le "new int(2)"
    	return 0;
    }
    C'est un exemple à ne pas utiliser, car il y a plusieurs très graves défauts, mais ca te permettra de sentir le concept.

    Si le pointeur était effectivement allouée dans le constructeur, on aurait affaire au design pattern RAII, qui est LA capacité du C++ que j'adore.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 46
    Par défaut
    Tout d'abord, merci à toi leternel !
    Mais les explications que tu fournis ne sont franchement pas à ma portée.
    De plus, tu proposes un code que tu déconseilles d'utiliser, je suis déconcerté.

    Finalement, j'ai trouvé une manière, bien sale certes, mais qui fonctionne.
    Je set simplement la propriété visible à false pour mes composants.

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Je déconseille d'utiliser mon code tel quel parce que unique_ptr/shared_ptr sont bien mieux codés, et vraiment sécurisé.
    Ce que j'ai présenté sert surtout à illustrer le concept.

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

Discussions similaires

  1. Depuis EDI DELPHI : Access Violation
    Par powerlog dans le forum EDI
    Réponses: 1
    Dernier message: 03/08/2005, 16h59
  2. Access violation avec fseek
    Par baleine dans le forum C
    Réponses: 7
    Dernier message: 18/03/2005, 16h41
  3. Réponses: 7
    Dernier message: 22/02/2005, 13h07
  4. [DELPHI][PROECEDURES STOCKES] Access violation
    Par All Jinx dans le forum Bases de données
    Réponses: 6
    Dernier message: 14/05/2004, 15h57
  5. Réponses: 3
    Dernier message: 22/05/2002, 09h37

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