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

Delphi Discussion :

recherche cause erreur EAccessViolation


Sujet :

Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 42
    Points
    42
    Par défaut recherche cause erreur EAccessViolation
    Bonjour,

    A la fermeture d'une fenetre, je tente de détruire tout ses composant en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    i := ComponentCount-1;
      While i > 0 do begin
            if Components[i].Owner.Name = Self.Name then Begin
              try
               Components[i].Destroy;
               i := ComponentCount-1;
              except
              end;
     
            end Else
              Dec(i);
      End;
    L'erreur "EAccessViolation" apparait, Mes composants sont créés dynamiquement, et il semble que cette erreur vienne d'un acces à la memoire qui n'existe pas...
    mon application travail en local et en reseau, il se trouve que cett erreur ne se produit qu'a la fermeture d'un dossier reseau (mais je ne vois pas pourquoi).

    Petit test réalisé, les EAccessViolation semble apparaitre pour la destruction de composant de type "PageCOntrol"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Components[i].name;
    m'a retourné des noms de composant de type: PC_4, PC_3 PC_2...
    mais je n'arrive pas à les identifier d'avantage. Y-a-t-il une methode pour trouver d'avantages d'infos sur ses composants?

    quels tests puis-je faire pour resoudre ces problemes d'acces memoire ou trouver quels composants son innaccessibles???

    merci pour toute idee pour avancer

    a bientot

    eric

  2. #2
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Points : 4 384
    Points
    4 384
    Par défaut

    d'après ton code, tu détruis tous les composant possédés par ta fenêtre, et là je me demande bien pourquoi ?
    car tu dois savoir que ta fenêtre libérera elle même tous les composants qu'elle possède à sa destruction. si tu n'essaie pas de libérer tes composants a la fermeture y a-til toujours une erreur ?

  3. #3
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    Bonjour.

    Si les comosants sont déclarés dans la partie Class de la fiche, il ne faut pas appeler leurs méthodes Destroy. Dailleur, Destroy ne doit jammais être appellé directement. C'est la méthode Free qui s'en charge. Mais dans le cas où les composant sont déclaé de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
        TForm1 = class(TForm)
     
     
         public
            Image1 : TImage;
            Edit1     : TEdit;
     
     
    ......
    Ils appartiènent au conteneur qu'est la fiche (TFom1). A la fermeture de la fiche les comosant sont automatiquement dédruis. Si un au appel à la méthode Destroy ou Free, il y a forcément une violation d'accès.
    Rien n'est moins sur que l'incertain : Pierre DAC

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par evarisnea
    si tu n'essaie pas de libérer tes composants a la fermeture y a-til toujours une erreur ?
    L'erreur apparait à la libération de la Fiche (EcDossier) contenant les composants:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         try
           EcDossier.Free;
           EcDossier := nil;
         Except
           EcDossier.Destroy;
           EcDossier := nil;
    //       ShowMessage('Attention destruction Dossier Level 2');
         end;

    aucun code n'est de moi, je tente seulement de debugger un petit peu un programme avec mes faibles connaissances Delphi, mais j'en apprend tous les jours sur ce forum !! merci


    Dailleur, Destroy ne doit jammais être appellé directement. C'est la méthode Free qui s'en charge.
    oui j'ai bien vu çà, mais ds la boucle de destruction de composants, le resultat est le même

  5. #5
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    Donne le code où est déclaré ecDossier, et le code où il est créé (méthode Creat).

    A+
    Rien n'est moins sur que l'incertain : Pierre DAC

  6. #6
    Membre averti Avatar de Bejaia-In
    Inscrit en
    Avril 2006
    Messages
    365
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 365
    Points : 392
    Points
    392
    Par défaut
    Est-ce que à un moment donné, dans le code, il-y-a création de composants ?
    Si oui ceux-là seulement doivent être libérés, sinon tu ne dois détruire rien du tout.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     EcDossier.Free;
     EcDossier := nil;
    Quelle est cette bizarerie ? libérer un composant pour lui donner une valeur nil ?
    ....................................................................
    Aidez-vous... Dieu vous aideras et nous aussi..
    ....................................................................

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 42
    Points
    42
    Par défaut
    Citation Envoyé par Bejaia-In
    Est-ce que à un moment donné, dans le code, il-y-a création de composants ?
    Si oui ceux-là seulement doivent être libérés, sinon tu ne dois détruire rien du tout.

    Quelle est cette bizarerie ? libérer un composant pour lui donner une valeur nil ?
    oui c'est bizarre hein, d'ailleurs l'auteur du programme a répété cette bizarrerie partout

    enfin bref, j'ai modifié la boucle de destruction des composants de ma Fiche qui sont créés dedans, ils sont tous detruits (libérés? je suis ne pas au point dans la rhétorique) sans erreurs
    et dans mon Main, à la place de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    EcDossier.Free;
    EcDossier := nil;
    je fais seulement
    et visiblement je n'ai plus d'erreur
    dans l'immédiat, çà me suffira, mais si quelqu'un a un peu de théorie sur la destruction d'objets/free/destroy et comment faire un code propre ds ces situations, je suis preneur car là je ne comprend pas tout


    pour Philippe Gormant je ne peux pas laisse le code du FormCreate car il est bcp trop long et sans commentaires, mais il créée essentiellement des boutons et des onglets en nombre TRES consequent....


    merci a tous

  8. #8
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    Si les composants sont déclarés dans la partie Class de la fiche, il ne faut pas appeler leurs méthodes Destroy ni la méthode free. Dailleur, Destroy ne doit jammais être appellé directement. C'est la méthode Free qui s'en charge. Mais dans le cas où les composant sont déclaé de cette façon :

    Code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    type
        TForm1 = class(TForm)
     
     
         public
            Image1 : TImage;
            Edit1     : TEdit;
     
     
    ......
    Ils appartiènent au conteneur qu'est la fiche (TFom1). A la fermeture de la fiche les composants sont automatiquement dédruis. Si un autre appel à la méthode Destroy ou Free, il y a forcément une violation d'accès.
    est parfaitement inutile.
    Rien n'est moins sur que l'incertain : Pierre DAC

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    52
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 52
    Points : 42
    Points
    42
    Par défaut
    Mes composants n'appartiennent pas à la TForm qui les créé, ils ne sont donc pas détruits automatiquement.

    Merci bcp pour les précisions!!


    Code :
    EcDossier := nil;est parfaitement inutile.
    C'est bien vrai !!!


    Merci a tous! Courage et Bonne Humeur !

  10. #10
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 557
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 557
    Points : 3 940
    Points
    3 940
    Par défaut
    Citation Envoyé par oiapoque
    Mes composants n'appartiennent pas à la TForm qui les créé, ils ne sont donc pas détruits automatiquement.

    Merci bcp pour les précisions!!



    Citation:
    Code :
    EcDossier := nil;est parfaitement inutile.


    C'est bien vrai !!!


    Merci a tous! Courage et Bonne Humeur !
    Bonjour

    je ne suis pas sûr d'avoir tout suivi mais ce genre de code doit amener à la suspicion, il est en général le signe d'une variable globale, l'affectation à nil permet de marquer l'allocation/la désallocation de l'objet de manière simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if not Assigned(ECDossier) then
      ecDossier := TEcDossier.Create;
    // plus loin dans l'application ...
    ecDossier.Free;
    ecDossier := Nil;
    Dans ce cas, l'affectation à nil a du sens et est même indispensable.
    Cependant je ne sais pas si cela correspond à la situation dans le code de oiapoque. C'est juste une remarque.

    En ce qui concerne la remarque
    Citation Envoyé par Philippe Gormand
    Ils appartiènent au conteneur qu'est la fiche (TFom1). A la fermeture de la fiche les composants sont automatiquement dédruis. Si un autre appel à la méthode Destroy ou Free, il y a forcément une violation d'accès.
    C'est partiellement vrai, les composants bien écrits doivent intégrer cette situation et informer leurs conteneur de leur libération (ce qui est le cas des composants Borland) qui doit être suffisament initelligent pour ne pas chercher à libérer des composants déjà détruits.
    Sinon, je ne vois pas pourquoi l'inverse serait valable à savoir qu'un conteneur puisse libérer des objets créés à la volée. Cela nous amènerait à une distinction forte entre composants instanciés automatiquement par la fiche et ceux créés à la volée par code, cette distinction ne va pas dans le sens de la robustesse des applications.

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  11. #11
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    Ouï ! Ouï ! Ouï !

    C'est partiellement vrai, les composants bien écrits doivent intégrer cette situation et informer leurs conteneur de leur libération (ce qui est le cas des composants Borland) qui doit être suffisament initelligent pour ne pas chercher à libérer des composants déjà détruits.
    Sinon, je ne vois pas pourquoi l'inverse serait valable à savoir qu'un conteneur puisse libérer des objets créés à la volée. Cela nous amènerait à une distinction forte entre composants instanciés automatiquement par la fiche et ceux créés à la volée par code, cette distinction ne va pas dans le sens de la robustesse des applications.
    L'objet TForm est non seulement un conteneur, mais c'est le Thread principal.
    Tout object déclaré dans l'objet TForm (le Thread principal ) est automatiquent détruit à la destruction (méthode Release ou Close) de la fiche. Cela fait partie des automatismes de DELPHI.

    Il suffit de faire quelque tests pour le constater. L'aide de DELPHI est très claire et très précise sur le sujet.

    Un TPanel par exemple, est un conteneur mais pas le Thread principal donc pas le conteneur principal. La gestion en est différente.

    Cela nous amènerait à une distinction forte entre composants instanciés automatiquement par la fiche et ceux créés à la volée par code, cette distinction ne va pas dans le sens de la robustesse des applications.
    Complètement faux. Cela permet justement une grande puissance de programmation, et une grande sécurité (à condition de bien la gérer).
    Rien n'est moins sur que l'incertain : Pierre DAC

  12. #12
    Membre averti Avatar de Bejaia-In
    Inscrit en
    Avril 2006
    Messages
    365
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 365
    Points : 392
    Points
    392
    Par défaut
    Voici l'implémentation de la méthode Free de tout objet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure TObject.Free;
    begin
      if Self <> nil then
        Destroy;
    end;
    on voit bien qu'affecter la valeur nil au composant est du pareil au même que d'appeller la méthode Free.
    ....................................................................
    Aidez-vous... Dieu vous aideras et nous aussi..
    ....................................................................

  13. #13
    Membre confirmé
    Avatar de Philippe Gormand
    Inscrit en
    Mars 2002
    Messages
    330
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 330
    Points : 647
    Points
    647
    Par défaut
    on voit bien qu'affecter la valeur nil au composant est du pareil au même que d'appeller la méthode Free.
    Mais non. La methode free test la valeur de NIL de l'objet pour le détruire. C'est à dire, libérer la mémoire et supprimer l'instance de l'objet en apellant la Méthode Destroy. Si on affect la valeur NIL à un objet avant d'appeller la méthode Free, Free ne pourra plus appeller la méthode Destroy.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    procedure TObject.Free;
    begin
      if Self <> nil then
        Destroy;
    end;
    C'est pourtant clair.
    Nil ne fait que que supprimer le référencement à un pointeur.
    Un objet est un pointeur. Si il a été détruit, son référencement a forcément la valeur NIL.
    Rien n'est moins sur que l'incertain : Pierre DAC

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

Discussions similaires

  1. Erreur EAccessviolation à l'execution
    Par bouzaidi dans le forum Delphi
    Réponses: 3
    Dernier message: 16/04/2007, 14h04
  2. Recherche multicritère erreur '3464' DCount()
    Par alex.a dans le forum Access
    Réponses: 8
    Dernier message: 18/05/2006, 13h57
  3. Message d'erreur Eaccessviolation
    Par Oluha dans le forum Bases de données
    Réponses: 2
    Dernier message: 04/11/2005, 13h59
  4. [ASP]resultSet = "" cause erreur???
    Par DEC dans le forum ASP
    Réponses: 2
    Dernier message: 19/07/2004, 17h56
  5. Erreur EACCESSVIOLATION avec des compsts créés dynamiquement
    Par tsikpemoise dans le forum Bases de données
    Réponses: 4
    Dernier message: 28/02/2004, 19h05

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