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 :

Tester la validité d'un pointeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut Tester la validité d'un pointeur
    Re-Bonjour,

    J'ai un pointeur sur un objet de la classe CMyCall dont j'aimerais tester la validité au cours de l'exécution du programme.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void f1(CMyCall* pCall)
    {
       f2(pCall);
    }
     
    void f2(CMyCall* pCall)
    {
      ...
      //Lance un thread avec pCall en paramètre
      AfxBeginThread( (AFX_THREADPROC) _ThreadProc, (LPVOID) pCall );
     
    }
    Or dans ce thread, j'aimerais tester pCall avant de faire des actions dessus (answer, speak, drop)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UINT thread(LPVOID par)
    {
      CMyCall*  pCall = (CMyCall*)par;
     
      if(pCall) pCall->Answer();
      if(pCall) pCall->Speak();
      if(pCall) pCall->Drop();
    }
    Donc tout le problème est que pCall peut être détruit ailleurs en cours de programme, et ensuite mis à NULL, lorsque l'appel a été raccroché par l'autre partie par exemple.
    La fonction qui se charge de ça, fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pCall->Deallocate();
    pCall = NULL;
    Quelle est la solution pour avoir accès au test if(pCall) dans mon thread, car là tel que j'ai fait le pointeur passé n'est pas averti de la mise à NULL ?

    @+

  2. #2
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Par défaut
    Une solution, c'est d'utiliser les smart_pointer de boost

    Enfin, je crois que c'est fait pour ça

  3. #3
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Par défaut
    Euh, ben sinon, au lieu de detruire ton objet par un delete, tu peut le detruire par un appel à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void deleteMyCall(CMyCall &(*pCall))
    {
        delete (&pCall);
        pCall = NULL;
    }
    Que tu definirais comme une fonction "globale"

    Je suis pas sûr du tout de la syntaxe, mais l'idée c'est de passer par référence un pointeur à la fonction. Celle-ci detruit l'objet pointé et met à NULL la variable référencée.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    CMyCall &(*pCall))
    Tu voulais dire CMyCall*& pCall ?

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    salut,
    merci pour ton idée, je ne vois pas en quoi cela change quoique ce soit, puisque'au final tu ne fais que pCall = NULL ...
    Je l'ai essayé et, à moins d'avoir mal fait, cela ne change rien.

    En effet si l'appel en cours est perdu, et donc que je désalloue l'appel et le met à NULL, je vois bien dans mon thread que mon pCall reste non NULL, mais pointe vers une zone mémoire libérée.

    Je sais bien que ceci est normal car en fin de compte je ne peux pas demander à tous les pointeurs référençant un objet de dévenir NULL lorsque je détruits cet objet et que je mets son pointeurs à NULL.

    Mais je cherche une solution ...

  6. #6
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Il te faut passer par un objet supplémentaire spécialisé dans la gestion de la vie de ton CMyCall. On t'a conseillé les pointeurs intelligents de boost, c'est un bon conseil.
    http://c.developpez.com/faq/cpp/?pag...OST_shared_ptr
    Combiné a un weak_ptr, tu peux obtenir l'effet recherché (tester la validité d'un pointeur), avec plus de sécurité (empecher la destruction de l'objet pendant qu'il est utilisé, car rien dans ton exemple n'empeche deleteMyCall() de détruire ton objet alors que pCall->Answer() est en cours d'exécution)

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Qu'il y ait pointeur intelligent ou non, il sera indispensable de faire du verrouillage: Comme l'a dit Aurelien (accent?), sans verrouillage l'objet pourrait être désalloué avant entre le moment où le thread vérifie et celui où il l'utilise.

    Au passage:
    Citation Envoyé par olive_le_malin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AfxBeginThread( (AFX_THREADPROC) _ThreadProc, (LPVOID) pCall );
    Le premier cast est très mauvais : Si ça ne compile pas sans la cast, c'est 80% de chances de plantage.
    Tu dois supprimer ton cast et corriger la signature de _ThreadProc au besoin.
    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.

  8. #8
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    C'est certain, une synchronisation avant d'utiliser le pointeur est necessaire si tu fais un delete quelque part ou pour tout acces non thread safe.

    Mais je maintiens que si tout tes threads possèdent un pointeur vers le pointeur principal, il n'y a plus de problèmes pour savoir quand ton pointeur n'est plus valide. Suffit de ne passer a chaque fois que du Objet** entre les interlocuteurs. C'est pas très contraignant à recoder.

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Danc ce genre de cas, je serais plutôt pour centraliser le pointeur lui-même dans une structure et passer partour un pointeur vers la structure en question: Cela permet d'éviter de se balader avec des ** partout.

    Ou encore, passer un objet qui renferme le pointeur de pointeur ou le pointeur de la structure contenant le pointeur. Les Smart Pointers de boost appartiennent à la catagorie "objet qui renferme le pointeur de la structure contenant le pointeur"...
    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.

  10. #10
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Ca à l'air pas mal alors.

    Il faudra que je me renseigne la dessus. J'ai toujours tendance à vouloir n'utiliser que le minimum de libs souvent au détriment de la complexité de mon code.

  11. #11
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par NiamorH
    Mais je maintiens que si tout tes threads possèdent un pointeur vers le pointeur principal, il n'y a plus de problèmes pour savoir quand ton pointeur n'est plus valide.
    La gestion de la concurrence est plus complexe qu'il n'y parrait.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(pCall) pCall->Answer();
    ton thread peut etre interrompu juste (ou peu) apres que le test ait réussit, et, pas de bol, l'autre thread peut détruire pCall a ce moment la. Résultat : Answer va etre exécuté sur un objet détruit...

    A partir du moment ou une ressource est partagée, il faut un mécanisme commun de gestion de la vie de cette ressource, sinon n'importe qui peut détruire la ressource pendant qu'un autre l'utilise.

  12. #12
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    non c'est certain cela ne remplace pas des synchronisations, mais je sais qu'à l'interieur des sections critiques j'aime bien faire des test if(m_truc) et etre sur que si mon objet n'est pas 0 alors il est toujours valide plutot que de faire appel a autre chose pour le determiner.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Dans ce cas, il peut être intéressant de mettre la section critique dans la même structure que le pointeur...
    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.

  14. #14
    Expert confirmé

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    Billets dans le blog
    3
    Par défaut
    Si on n'utilise que des pointeurs intelligents, comment l'objet peut-il etre détruit durant l'exécution d'une de ses opérations ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    weak_ptr<CMyCall> pCall;
     
    if(shared_ptr<CMyCall> p = pCall.lock())
    {
        p->Answer();
    }
    par contre, pour passer le weak_ptr en parametre au thread, c'est pas evident.

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Pour ça, je pense qu'il faudra le "boxer" sur le tas, avec un pointeur stupide, pour le passer au thread.
    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.

  16. #16
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    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 296
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Si on n'utilise que des pointeurs intelligents, comment l'objet peut-il etre détruit durant l'exécution d'une de ses opérations ?
    Depuis un autre thread. Il suffit d'un delete this. Juste avant de le déclencher, il faut notifier tous les observateurs que la vue sur la ressource encapsulée n'est plus utilisable.

    Mais j'avoue que tu me mets le doute. N'ayant pas eu accès à boost (question de génération de compilo), j'ai dû réinventer des roues spécialisées à mes problèmes.
    Il n'est finalement peut-être pas impossible qu'uniquement avec des weak_ptr, et peut-être même un "enable shared from this" on s'en sorte, c'est à étudier.
    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...

Discussions similaires

  1. [VB.NET] Comment tester la validité d'une date ?
    Par Zefree dans le forum ASP.NET
    Réponses: 5
    Dernier message: 15/12/2012, 15h49
  2. Comment tester la validité d'une adresse mail
    Par jmoez dans le forum Oracle
    Réponses: 1
    Dernier message: 19/04/2006, 13h00
  3. [pointeur] Tester la validité
    Par Luffy Duck dans le forum C++
    Réponses: 13
    Dernier message: 16/01/2006, 17h39
  4. Comment tester la validité d'un répertoire?
    Par Gabrielly dans le forum MFC
    Réponses: 5
    Dernier message: 25/02/2005, 11h13
  5. [web] tester la validiter d'une URL
    Par zebiloute dans le forum Web
    Réponses: 4
    Dernier message: 25/11/2002, 16h51

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