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 :

Comment savoir si un pointeur a été delete ?


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 19
    Points : 10
    Points
    10
    Par défaut Comment savoir si un pointeur a été delete ?
    Hello, j'aimerais pouvoir tester si un pointeur *p a était delete (via delete p; ).
    Je sais que normalement, on ne devrait pas avoir a tester ce genre de chose, mais la n'est pas la question. Je sais également qu'il existe _CrtIsValidPointer sous windows, mais j'aimerais sous équivalent sous unix pour gcc.

    Merci

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 124
    Points : 148
    Points
    148
    Par défaut
    Tu peux pas coder ta propre fonction ?
    Tu surcharge l'opérateur delete et tu donnes la valeur NULL a un pointeur ?
    C'est pas si difficile...

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2008
    Messages : 308
    Points : 622
    Points
    622
    Par défaut
    pas bête

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 19
    Points : 10
    Points
    10
    Par défaut
    A vrai dire, j'ai déja essayer de surcharger l'operateur delete pour mettre ma variable p = NULL, mais une fois en dehors de la fonction delete, p retournée la valeur d'origine

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 124
    Points : 148
    Points
    148
    Par défaut
    C'est etrange...
    Montre le code ?
    Ou fait toi une macro :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define SAFE_DELETE(a) { delete (a); (a) = NULL; }

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    A priori, sans un support du runtime (ce qui est le cas dans Windows avec _CrtIsValidPointer) ou sans macro comme celle proposée ci-dessus, tu n'as aucun moyen de savoir si un pointeur est encore valide ou pas, pour la simple et bonne raison que l'adresse qu'il contient EST une adresse valide et accessible (=pas de "segmentation fault")... Les données contenues sont certes aberrantes et/ou celles d'un autre objet, OK, mais le pointeur reste intrinsèquement "valide" pour le processus courant !!

  7. #7
    screetch
    Invité(e)
    Par défaut
    euh oui et non, la mémoire peut ne plus appartenir au processus selon ce que fait "new" et "delete", ce n'est vraiment plus valide

    pour la macro delete, pourquoi pas plutot une fonction template que cette vilaine macro ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template< typename T >
    void safe_delete(T* & ptr)
    {
      delete ptr;
      ptr = 0;
    }

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 19
    Points : 10
    Points
    10
    Par défaut
    Je vais tester ta macro, je viens de remplacer tous mes delete par celle-ci, je vais recompiler et faire quelque test Je vous tiens au courant, merci pour l'aide aussi rapide !

  9. #9
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par screetch Voir le message
    euh oui et non, la mémoire peut ne plus appartenir au processus selon ce que fait "new" et "delete", ce n'est vraiment plus valide
    A priori, le pointeur est toujours dans l'espace de mémoire mappé du processus... Donc, accessible sans faire une erreur de segmentation.
    Le contenu est par contre toujours aberrant, et le déréférencement du pointeur est (au mieux !!) hasardeux si c'est un pointeur sur une structure complexe (genre classe).

    Bien sûr, c'est assez différent dans le cas d'allocations directement faites via le système d'exploitation, puis mappées dans le processus (ex : VirtualAlloc sous Windows), mais habituellement ce n'est pas le cas des fonctions comme malloc/new qui utilisent un tas privé pour le processus pour des raisons de performances. Et du coup, les pointeurs restent hélas "valides" s'ils ne sont pas mis à NULL...

  10. #10
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    A priori, le pointeur est toujours dans l'espace de mémoire mappé du processus... Donc, accessible sans faire une erreur de segmentation.
    Le contenu est par contre toujours aberrant, et le déréférencement du pointeur est (au mieux !!) hasardeux si c'est un pointeur sur une structure complexe (genre classe).

    Bien sûr, c'est assez différent dans le cas d'allocations directement faites via le système d'exploitation, puis mappées dans le processus (ex : VirtualAlloc sous Windows), mais habituellement ce n'est pas le cas des fonctions comme malloc/new qui utilisent un tas privé pour le processus pour des raisons de performances. Et du coup, les pointeurs restent hélas "valides" s'ils ne sont pas mis à NULL...
    bah rien n'est sur... le bloc peut etre reutilisé, ou etre rendu au systeme d'exploitation si on en a plus besoin

    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main()
    {
        int* a = new int[1*1024*1024];;
        delete[] a;
        *a = 0;
        return 0;
    }
    ca ca plante chez moi avec une segmentation fault

  11. #11
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par Izidor's Voir le message
    Je vais tester ta macro, je viens de remplacer tous mes delete par celle-ci, je vais recompiler et faire quelque test Je vous tiens au courant, merci pour l'aide aussi rapide !
    je me repete peut etre mais la macro est un peu crade, le code template plus haut est un peu plus sur (notamment parce que SAFE_DELETE(p++) va planter)

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par screetch Voir le message
    bah rien n'est sur... le bloc peut etre reutilisé, ou etre rendu au systeme d'exploitation si on en a plus besoin
    Mais tu ne "vois" rien d'anormal sur le pointeur si tu l'affiches : il a une valeur "légitime", qui peut être à priori déréférencée (ou pas, bien sûr). Il n'a absolument aucune valeur "reconnaissable", et peut même être très proche d'un pointeur 100% valide. Visual Studio provoque en général des erreurs de segmentation, mais d'autres compilateurs / OS peuvent au contraire systématiquement laisser passer un tel code sans planter immédiatement.

    D'où la nécessité soit d'avoir soit une assistance de la part du runtime, soit d'avoir des mises à NULL explicites lors des destructions. Sans ça, aucun moyen de savoir si un pointeur est encore valide ou pas.

  13. #13
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    Cette technique est un pur non-sens.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int* a = new int(42);
    int* b = a;
    safe_delete(a);
    b ne vaut pas 0.
    Bref ça ne marche que dans le cas où il n'y a pas d'aliasing, qui s'exprime cent fois mieux par du RAII où de toutes manières le pointeur ne peut jamais être libéré tant qu'il est utilisé...

    Sinon, il faut utiliser shared_ptr avec weak_ptr, qui va réellement faire en sorte que toutes les références deviennent nulles, en prenant en compte les problèmes non seulement d'aliasing et de partage de propriété, mais aussi de concurrence.

    Ce qui est fou c'est qu'on sait quelles sont les bonnes manières de gérer les ressources en C++, et qu'il y en a très peu, mais il y en a encore qui insistent pour faire n'importe quoi...

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    124
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 124
    Points : 148
    Points
    148
    Par défaut
    @loufoque : tu ne fais que montrer pourquoi delete ne mets pas un pointeur à 0...
    On cherche pas une méthode générique mais un fonctionnement précis pour un pointeur et non pas tout les pointeurs sur une même adresse.

    PS : La fonction template sera plus lente que la macro dans certains cas, c'est pourquoi j'ai préférer faire une macro

  15. #15
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Cette technique est un pur non-sens.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int* a = new int(42);
    int* b = a;
    safe_delete(a);
    b ne vaut pas 0.
    Bref ça ne marche que dans le cas où il n'y a pas d'aliasing, qui s'exprime cent fois mieux par du RAII où de toutes manières le pointeur ne peut jamais être libéré tant qu'il est utilisé...

    Sinon, il faut utiliser shared_ptr avec weak_ptr, qui va réellement faire en sorte que toutes les références deviennent nulles, en prenant en compte les problèmes non seulement d'aliasing et de partage de propriété, mais aussi de concurrence.

    Ce qui est fou c'est qu'on sait quelles sont les bonnes manières de gérer les ressources en C++, et qu'il y en a très peu, mais il y en a encore qui insistent pour faire n'importe quoi...
    l'avantage (le seul) du safe_delete c'est que ca crash immediatement lorsqu'on déréférence le pointeur, ce n'est effectivement en aucun cas une gestion des ressources, c'est meme complétement orthogonal a une gestion des resources.
    et ca reste une bonne pratique de faire pointer ton pointeur dans la moquette pour eviter de modifier une valeur mémoire au pif, meme si ca ne te permet pas de gerer tes ressources.

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 19
    Points : 10
    Points
    10
    Par défaut
    J'ai finalement utiliser le template. Pour un pointer simple, ca va. Le seul problème est qu'il y a des pointeurs qui sont référencés un peut partout, et du coup sa ne met a NULL que le pointeur ciblé.

    Je pense, comme suggéré plus haut qu'un shared_ptr est une bonne solution a mon problème. Je me suis renseignée un peu, mais quel sont les avantages du shared_ptr de boost par rapport a auto_ptr de la STL ?

    Également, l'utilisation des pointeurs intelligent consomme t'il beaucoup de mémoire en plus ou pas ? Étant donnez que mon application consomme déjà 75 % de mémoires disponible sur ma machine serveur ...

    Merci

  17. #17
    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
    Points : 4 625
    Points
    4 625
    Par défaut
    Je me suis renseignée un peu, mais quel sont les avantages du shared_ptr de boost par rapport a auto_ptr de la STL ?
    Ce sont des choses totalement différentes.
    Par ailleurs, auto_ptr est déprecié au profit de unique_ptr en C++0x.

    Également, l'utilisation des pointeurs intelligent consomme t'il beaucoup de mémoire en plus ou pas ?
    Un mot de plus par objet alloué avec make_shared. Si tu n'utilises pas make_shared, l'utilisation mémoire sera plus importante et fragmentée.

  18. #18
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ce sont des choses totalement différentes.
    Par ailleurs, auto_ptr est déprecié au profit de unique_ptr en C++0x.


    Un mot de plus par objet alloué avec make_shared. Si tu n'utilises pas make_shared, l'utilisation mémoire sera plus importante et fragmentée.
    Le dernière fois que j'avais vérifié il me semble que c'était plus que ça (à cause de weak_ptr qui est trainé comme une casserole dans les 99% des cas où on n'en a pas besoin ?).

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

Discussions similaires

  1. Comment savoir si on a les acces read/write/delete sur un répertoire ?
    Par noooop dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 10/05/2010, 17h28
  2. Comment savoir qu'un objet est delete
    Par yupa dans le forum C++
    Réponses: 11
    Dernier message: 25/10/2007, 18h04
  3. comment savoir ce que fait mon pointeur??
    Par elekis dans le forum C++
    Réponses: 9
    Dernier message: 30/11/2004, 13h42
  4. Réponses: 9
    Dernier message: 11/03/2003, 13h22
  5. Réponses: 4
    Dernier message: 10/09/2002, 18h09

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