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 :

[C++] Libération de mémoire de void*


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Par défaut [C++] Libération de mémoire de void*
    Bonjour,

    Je suis confronté à un petit problème : j'utilise la librairie pthread pour gérer le multithreading (je n'ai pas accès à std::thread non supporté par mon compilateur) et je code en C++. Le prototype de la fonction callback qui fera le travail du thread est la suivante : void* callback(void* arg); et donc travaille sur des pointeurs génériques (void*).

    Le problème est que faire un delete sur un void* provoque un comportement indéfini d'après la documentation.

    Comment faire pour supprimer la mémoire alloué au paramètre "arg" si à un moment donné j'ai perdu la vraie nature de la classe que j'ai passé en paramètre ? Est ce que faire un free appelerait le destructeur de la classe ?

    Exemple : Soit une classe Dummy.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Dummy* d = new Dummy();
    pthread_t thread;
    pthread_create(&thread, callback, NULL, d);
     
    // et plus loin dans le programme dans une autre fonction je dois supprimer la mémoire allouée par "d" mais j'ai perdu le type réel du pointeur à savoir pointeur sur classe Dummy. Je ne peux donc pas caster et faire un delete après....
    Merci et bonne journée
    Qui ne tente rien n'a rien !
    Ce qui ne nous tue pas nous rends plus fort !!
    Mon projet ZELDA en C++/Allegro
    http://www.tutoworld.com - Le Forum -
    Mes ressources Dotnet (cours, sources, tutos)
    --------------------------------------------
    + + =

    Ne pas oublier le Tag !

  2. #2
    Invité
    Invité(e)
    Par défaut
    Je ne suis pas expert mais pour la première question je dirais que si tu as perdu la nature de la classe passé en paramètre c'est mort, sauf si le compilateur insère des mécanisme permettant de ... (j'en doute fort), et pour la seconde question je dirais non, un free ne va pas appeler le destructeur.
    Mais pourquoi est ce que tu ne libères pas la mémoire aprés avoir appeler callback(), ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *ptr = new char [256]; callback( ( void *)ptr); delete [] ptr;
    C'est plus sûr non?
    Dernière modification par LittleWhite ; 20/03/2016 à 18h51. Motif: Pas besoin de citer l'intégralité du message précédent

  3. #3
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 760
    Par défaut
    Citation Envoyé par Ratator Voir le message
    Mais pourquoi est ce que tu ne libères pas la mémoire aprés avoir appeler callback(), ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *ptr = new char [256]; callback( ( void *)ptr); delete [] ptr;
    C'est plus sûr non?
    Peut-être parce que c'est une callback

    Par définition, une callback peut-être appelée à n'importe quel moment: à la fin ou au début d'un traitement, à la réception d'un événement ...

    La solution que je vois (mais il faut attendre les experts) c'est de rendre ce pointeur plus ou moins global: soit carrément global, soit encapsuler dans une classe qui contient que les données de l'application (AppData), soit dans la classe principale, soit ...

    Il faut le laisser vivre sa vie et lorsque c'est possible (*), vérifier son état et le détruire en conséquence.

    * -> Par d'exemple à la création d'un nouveau thread, après un pthread_join, à la fin du programme, ...

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Tu peux utiliser un type commun à tous tes arguments, et laisser l'héritage se charger de retrouver le type pour toi et appeler le bon dtor.

    Toutes les classes ont au moins 1 point commun : elles ont un dtor, ça fait une base correcte pour tes arguments.
    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
    #include <iostream>
     
    struct Arg {
    	virtual ~Arg() = 0 { }
    };
     
    struct Dummy_0 : Arg {
    	~Dummy_0() { std::cout << "Dummy_0" << std::endl; }
    };
     
    struct Dummy_1 : Arg {
    	~Dummy_1() { std::cout << "Dummy_1" << std::endl; }
    };
     
    void foo(void *arg) {
    	Arg *a = reinterpret_cast<Arg*>(arg);
    	delete a;
    }
     
    int main() {
     
    	foo(reinterpret_cast<void*>(new Dummy_0));
    	foo(reinterpret_cast<void*>(new Dummy_1));
     
    	return 0;
    }

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Par défaut
    Est-ce que tu es vraiment obligé d'utiliser des pointeurs? Voici ce que j'aurais fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dummy d;
    pthread_t thread;
    pthread_create(&thread, callback, NULL, static_cast<void*>(&d));

  6. #6
    Membre chevronné Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 58
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Par défaut
    Citation Envoyé par darkman19320 Voir le message
    Est-ce que tu es vraiment obligé d'utiliser des pointeurs? Voici ce que j'aurais fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dummy d;
    pthread_t thread;
    pthread_create(&thread, callback, NULL, static_cast<void*>(&d));
    Bonjour,

    La méthode que tu préconises est très mauvaise. Si après le pthread_create on sort du scope de d, d se detruit. Mais rien ne dit que la callback aura fini d'utiliser les données, rien ne dit qu'elle aura été appelée.

    Nous sommes en environnement multithread et que nous ne savons pas quand la fonction de callback aura utilisé la variable passée en paramètre. Il faut donc s'assurer que :
    - soit la destruction de cette variable est sous le contrôle de la callback
    -> en la détruisant elle même.
    -> en signalant qu'elle peut être détruite.
    - soit le thread appelant ne détruit la variable qu'une fois le thread appelé terminé (c'est à ça que sert pthread_join).
    Mais en aucun cas, le thread appelant ne doit détruire cette variable sans contrôle.

    Aspic, pour utiliser ton pointeur, ta callback doit connaitre son type exact. Donc a priori, tu doit pouvoir la détruire sans problème.

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 27/05/2006, 13h30
  2. Problème libération de mémoire?
    Par Bartuk dans le forum C
    Réponses: 7
    Dernier message: 28/12/2005, 17h20
  3. Libération de mémoire
    Par petitcoucou31 dans le forum Langage
    Réponses: 1
    Dernier message: 16/09/2005, 14h10
  4. [Debutant(e)]problème de libération de mémoire
    Par skywalker3 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 10/02/2005, 17h38
  5. Réponses: 25
    Dernier message: 16/07/2003, 20h41

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