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 :

Memory leak ou fuite de mémoire


Sujet :

C++

  1. #1
    bruce-willis
    Invité(e)
    Par défaut Memory leak ou fuite de mémoire
    Salut tout le monde!

    En quoi le memory leak (dont je définis comme l'oubli de désallouer une zone allouée avec new) constitue un risque pour un programme?
    En effet, le programme occupera plus d'espace dont une partie inutilisée, celle de la zone non désallouée. Est-ce que c'est une FAILLE au même titre que le STACK OVERFLOW (dépassement de la pile)?
    Comment un programme sait qu'une zone est allouée en fait? Est-ce qu'il y a une sorte de table d'allocations ou du genre (compilateur C++) ???

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Le risque est quand ce phénomène se passe dans une boucle. Au bout d'un moment, tu auras bouffé toute la mémoire de ta machine.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Salut tout le monde!
    Plop.

    En quoi le memory leak (dont je définis comme l'oubli de désallouer une zone allouée avec new) constitue un risque pour un programme!
    Et bien, la fuite de mémoire est un risque car ton programme va au final utiliser de plus en mémoire car il ne libère pas tout ce qu'il demande. Donc au bout d'un moment la mémoire va se faire rare, et le système ralentir/planter. C'est d'autant plus visible que le code responable de la fuite est appelé souvent.

    En effet, le programme occupera plus d'espace dont une partie inutilisée, celle de la zone non désallouée. Est-ce que c'est une FAILLE au même titre que le STACK OVERFLOW (dépassement de la pile)?
    Ce n'est pas une faille. Avec une fuite de mémoire, tu ne pourra jamais obtenir les droits root sur une machine. Par contre, ca peut être un moyen de faire planter une machine.

    Comment un programme sait qu'une zone est allouée en fait? Est-ce qu'il y a une sorte de table d'allocations ou du genre (compilateur C++) ???
    Ca je ne comprend pas. Ya 2 grand type d'allocation en C++ : statique et dynamique. En gros, l'alloc statique, c'est le programme qui gère les variables.
    En dynamique, c'est toi qui les construit explicitement (avec new) et qui les détruit (avec delete). Il ne peut y avoir de fuite de mémoire qu'avec la 2eme méthode.

    Pour info, il y a de cela quelque temps, une fuite de mémoire dans un logiciel hospitalier entraînait un blocage complet du système, empêchant ainsi la bonne distribution des ambulances causant de fait la mort de personnes.
    C'est un exemple extrème, mais ca prouve qu'une fuite de mémoire ca n'est jamais rien.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  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
    L'allocation dynamique, en général, tu demandes à l'OS de t'allouer des pages mémoires (chaque processus a une table des pages mémoires qui lui ont été allouées) puis après tu te débrouilles pour les partitionner pour mettre tes données dessus.
    Par exemple, mmap permet d'allouer une page, et malloc/free vont l'appeler au besoin, puis t'en filer des petits bouts au fur et à mesure, en redécoupant la page en blocs qui contiendront éventuellement des informations nécessaires à l'allocateur. (dans le cas de malloc/free, il est bien sûr nécessaire de stocker la taille allouée)

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 465
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 465
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Ca je ne comprend pas. Ya 2 grand type d'allocation en C++ : statique et dynamique. En gros, l'alloc statique, c'est le programme qui gère les variables.
    En dynamique, c'est toi qui les construit explicitement (avec new) et qui les détruit (avec delete). Il ne peut y avoir de fuite de mémoire qu'avec la 2eme méthode.
    Attention : contrairement à ce que l'intuition pousse à croire, les variables locales sont une forme d'allocation dynamique : elles sont bien réservées au runtime dans la pile à chaque entrée dans le bloc, en déplaçant le pointeur de pile et en réinitialisant leur contenu à chaque fois si une valeur par défaut est précisée dans le code ! Une fonction récursive mal contrôlée peut d'ailleurs déclencher un stack overflow.

    Les cas dans lesquels on peut parler d'allocation statique sont pour moi : le code proprement dit, les constantes, les variables globales et les variables locales statiques (globalisées en pratique).

  6. #6
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Attention : contrairement à ce que l'intuition pousse à croire, les variables locales sont une forme d'allocation dynamique : elles sont bien réservées au runtime dans la pile à chaque entrée dans le bloc, en déplaçant le pointeur de pile et en réinitialisant leur contenu à chaque fois si une valeur par défaut est précisée dans le code ! Une fonction récursive mal contrôlée peut d'ailleurs déclencher un stack overflow.

    Les cas dans lesquels on peut parler d'allocation statique sont pour moi : le code proprement dit, les constantes, les variables globales et les variables locales statiques (globalisées en pratique).
    Je sais ceci, mais j'ai volontairement simplifier d'où mon "En gros".
    Car c'est le genre de détail qu'on peut très facilement sauter quand on débute.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  7. #7
    bruce-willis
    Invité(e)
    Par défaut
    Ca je ne comprend pas. Ya 2 grand type d'allocation en C++ : statique et dynamique. En gros, l'alloc statique, c'est le programme qui gère les variables.
    En dynamique, c'est toi qui les construit explicitement (avec new) et qui les détruit (avec delete). Il ne peut y avoir de fuite de mémoire qu'avec la 2eme méthode.
    En effet, je parle de l'allocation dynamique!!!
    Ce que j'aimerais comprendre c'est l'allocation de new même. Comment le programme sait que tel espace est libre pour y placer la classe allouée par new ? Y a-t-il une sorte de table?
    tu demandes à l'OS de t'allouer des pages mémoires
    Pour une allocation de 500 octets seulement!

    Une allocation new peut-elle se faire dans la pile (stack)???

  8. #8
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    264
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 264
    Par défaut
    En effet, je parle de l'allocation dynamique!!!
    Ce que j'aimerais comprendre c'est l'allocation de new même. Comment le programme sache que tel espace est libre pour y placer la classe allouée par new ? Y a-t-il une sorte de table?
    C'est le système d'exploitation qui s'occupe de gérer la mémoire de ton ordinateur. C'est lui qui lui dit d'utiliser telle ou telle plage.

    Une allocation new peut-elle se faire dans la pile (stack)???
    Pas à ma connaissance. Il y a bien alloca() qui alloue de la mémoire dans la pile, mais ça ne fait pas ce que fait new (n'appelle pas de contructeur pour tes objets), c'est plus proche de malloc(). À éviter.

  9. #9
    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
    Certains allocateurs tentent aussi d'agrandir le segment data, mais c'est très limité.

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 465
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 465
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Je sais ceci, mais j'ai volontairement simplifier d'où mon "En gros".
    Je m'en doute, mais mon commentaire était surtout à l'intention de l'auteur du fil.

    Car c'est le genre de détail qu'on peut très facilement sauter quand on débute.
    D'où mon message ! :-)

  11. #11
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 465
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 465
    Par défaut
    Citation Envoyé par bruce-willis Voir le message
    Salut tout le monde!

    En quoi le memory leak (dont je définis comme l'oubli de désallouer une zone allouée avec new) constitue un risque pour un programme!
    En effet, le programme occupera plus d'espace dont une partie inutilisée, celle de la zone non désallouée. Est-ce que c'est une FAILLE au même titre que le STACK OVERFLOW (dépassement de la pile)?
    Comme dit plus haut, ce n'est pas directement une faille dans la mesure où tu ne risques pas d'écraser d'autres données. Par contre, ça peut le devenir si l'allocation de mémoire non libérée se fait sur un événement utilisateur extérieur. Par exemple, si tu écris un serveur web, que ta page alloue un formulaire, et celui-ci est libéré une fois que l'utilisateur l'a soumis, alors il me suffit d'appeler en boucle ta page sans jamais passer à la suivante pour être sûr de planter ton serveur à distance, au bout d'un moment.

    Comment un programme sait qu'une zone est allouée en fait? Est-ce qu'il y a une sorte de table d'allocations ou du genre (compilateur C++) ???
    Oui, tout-à-fait, et les problèmes relatifs sont les mêmes qu'avec un système de fichier (fragmentation). D'ailleurs, les différentes approches et algorithmes de gestion efficace de la mémoire font l'objet d'études avancées. Voir SLAB par exemple.

    D'ailleurs, en travaillant en mode réel (ou assimilé, pas seulement sur Intel, je veux dire), on avait un problème supplémentaire, puisque les programmes obtenaient des pointeurs sur l'adresse physique (c'est à ça qu'ils servent, initialement). Donc, on ne pouvait pas déplacer à la volée les plages allouées pour faire du ménage. Avec le mode protégé, est apparu un nouveau mode d'adressage, qui instaure effectivement une table, gérée électroniquement : la GDT. Cette couche d'abstraction transparente est très utile avec l'augmentation de la mémoire disponible et le nombre toujours croissant de programme tournant en parallèle.

  12. #12
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    D'abord il faut bien comprendre que "new" est une opérateur "haut-niveau", dans ce sens ou il fait PLEIN de choses, et surtout, qu'il peut être surchargé !

    Un new fait deux choses:
    - Allocation de l'espace mémoire pour l'objet en question- Appel du constructeur de cet objet.

    La partie verte peut être surchargé par l'objet lui-même, ou l'environnement de compilation (le new 'global' du namespace de l'objet). Donc chaque objet peut choisir sa propre allocation mémoire (je donnerai un exemple ci-dessous).

    Ensuite pour les allocations mémoires tout dépend de l'OS et des fonctions qu'il propose... Windows ne propose pas moins de 4 types d'allocation. Mais aucune de celle-ci n'est utilisée par le "new" par défaut... le "new" par défaut utilise "malloc", qui lui même va utiliser une des fonctions de l'OS *en modifiant l'appel*... Par exemple, en stockant la taille de la zone allouée en début de zone:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void* malloc(size_t size)
    {
         size_t* os_result = os_allocation_function(size + sizeof(size_t));
         *os_result++ = size;
         return os_result;
    }
    Ce qui permet au "free" associé de retrouver cette taille:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void free(void* ptr)
    {
        size_t* os_zone = (size_t*)ptr;
        --os_zone;
        os_deallaction_function(os_soze,*os_zone + sizeof(size_t));
    }
    En debug, malloc et free vont faire plein d'autre chose: rajouter des valeurs "interdites avant et après la zone", stocker le nom du fichier (et la ligne) à laquelle l'allocation est faite, empiler la zone en question dans une liste de zones allouées, et ainsi, être capable de renvoyer à tout moment, qui a alloué quoi et quand... [et au passage vérifier que personne n'a touché aux données *autour* de la zone alloué].

    Maintenant, on peut tout à fait implémenter soi même un allocateur un peu plus rapide que celui de windows.... D'autant que celui de windows est nécessaire thread-safe ! (et donc passe du temps dans les fonctions de thread synchronisation).
    Si, par exemple, j'ai un groupe de 10.000 objets de 256 octets... Je peux faire 10.000 fois un malloc, ou bien 1 seule fois un malloc de 2.560.000 octets, et faire moi-même la gestion mémoire là dedans...

  13. #13
    bruce-willis
    Invité(e)
    Par défaut
    Ok merci

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 17
    Par défaut
    Les fuites mémoire sont considérées par la plupart des outils qui les "trackent" comme des "warning" car elles ne mettent pas en péril immédiatement ton programme, mais vont conduire inexorablement ton programme dans le mur puisque la mémoire n'est jamais récupérée tant que ton processus existe.

    Quand tu utilises plusieurs heures un programme qui fuit, en général tu fini par ne plus pouvoir allouer de la mémoire et de toute façon ton logiciel est grandement ralenti puisque ton programme fini par "swapper" ses pages mémoires sur ton disque.

    Un utilitaire (gratuit) de Microsoft permet de les découvrir dans ton processus : "Debug diagnostic tools de Microsoft" pour les programmes Windows bien évidemment :
    http://bertrandleclercq.blogspot.com...vec-debug.html

    Bonne chance Elles sont difficiles à cerner en général, "noyées" dans des logs difficiles à interpréter.

  15. #15
    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
    Avec valgrind, les erreurs mémoire et les fuites se trouvent facilement.
    Après, si tu suis le RAII, tu ne peux pas avoir de fuites mémoire de toute façon...

  16. #16
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Un exemple de leak fourbe (mais connu) qui me fais dire que penser RAII seul ne suffit pas pour éviter les leaks:

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    #include <map>
     
    class BaseClass
    {
    public:
     
    	explicit BaseClass()
    	{
    	}
     
    	~BaseClass()
    	{
     
    	}
     
     
    	virtual int doVirtual( int i )=0;
     
    };
     
     
    class LeakingClass : public BaseClass
    {
    public:
     
    	int doVirtual( int i ){ int k = i; ++k; return k+i; }
     
    private:
    	std::map< int, int> m_testMap;
    };
     
    class MasterClass
    {
    public:
     
    	MasterClass()
    	{
    		testObject = new LeakingClass;
    	}
     
    	~MasterClass()
    	{
    		delete testObject;
    	}
     
     
    private:
     
    	BaseClass* testObject;
     
    };
     
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
     
    int main(int argc, char *argv[])
    {
    	// First simple memory leak detection for VS2005/VS2008
    #if (defined( WIN32 ) || defined( _WIN32 )) && defined( _MSC_VER ) && defined( _DEBUG )  
    	// use _crtBreakAlloc to put a breakpoint on the provided memory leak id allocation
    	//_crtBreakAlloc = 1914;
    	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
     
    #endif
    	int result = 0; 
     
    	MasterClass testMaster;
     
    	return result;
     
    }
    Cette application compilée sous Visual Studio 2008 fais du memory leak :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    'Test_VirtualInheritanceHell.exe': Loaded 'E:\Tests\Test_VirtualInheritanceHell\Debug\Test_VirtualInheritanceHell.exe', Symbols loaded.
    'Test_VirtualInheritanceHell.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll'
    'Test_VirtualInheritanceHell.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll'
    'Test_VirtualInheritanceHell.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\msvcp90d.dll', Symbols loaded.
    'Test_VirtualInheritanceHell.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_f863c71f\msvcr90d.dll', Symbols loaded.
    Detected memory leaks!
    Dumping objects ->
    {137} normal block at 0x00343B80, 24 bytes long.
     Data: < ;4  ;4  ;4     > 80 3B 34 00 80 3B 34 00 80 3B 34 00 CD CD CD CD 
    Object dump complete.
    The program '[3988] Test_VirtualInheritanceHell.exe: Native' has exited with code 0 (0x0).
    C'est la reproduction d'un memory leak trouvé dans la dernière RC1 d'OGRE.

    Comme la source du leak ici est dûe à l'absence de virtual dans le destructeur de la classe de base, on peut considérer que le problème est purement dû à une erreur dans l'implémentation du RAII. Erreur pas forcément facile a tracker dans le système de script d'Ogre par exemple.

    Personnellement, je préfère partir du principe qu'il est possible d'avoir un leak même en suivant scrupuleusement le RAII, et ne pas me fermer des portes quand je cherche la source d'un leak qui théoriquement ne devrait pas exister. Parceque l'erreur viens du développeur.

  17. #17
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Sauf qu'en l'occurence, ce n'est pas une fuite mémoire, c'est encore plus grave, c'est un comportement indéfini.

    Si je devais maintenir une base de code avec ce genre de choses, je pense que je me pencherais sur des outils d'analyse statique genre lint.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  18. #18
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Ah oui tiens j'ai essayé avec une variante (ajouter une classe suplémentaire dans la hierarchie et l'utiliser a la place de LeakClass) et j'ai carrément une erreur au delete (block invalide).

    Comme quoi, un memory leak peut aussi être issu d'un comportement indéfini... ( O__O;; )

    Quelqu'un peut tester voir sous gcc?

  19. #19
    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
    Il n'est possible d'appeler delete que sur un objet qui a été alloué par new et avec un pointeur dont le type est le même que celui utilisé pour allouer cet objet. C'est pour cela, en particulier, qu'il n'est pas autorisé d'appeler delete sur un void*.
    Une exception à cette règle est qu'il possible d'appeler delete avec un pointeur vers une base du type alloué, uniquement si cette base a un destructeur virtuel.

    Tout autre usage de delete est un comportement indéfini.
    Ceci n'a rien à avoir avec le RAII. S'il y a une fuite, c'est parce que sur une implémentation classique ceci va appeler le constructeur de BaseClass et non le bon, celui de LeakingClass.

  20. #20
    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
    Ce qui fait qu'en l'occurence, il est facile de corriger l'erreur: Il suffit de rendre virtuel le destructeur de BaseClass...

    D'une manière générale, GotW recommande que le destructeur d'une classe de base soit toujours virtuel s'il est public. S'il n'est pas virtuel, alors il doit être protected.
    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.

Discussions similaires

  1. EclipseLink et memory leak (fuite mémoire)
    Par jmturc dans le forum JPA
    Réponses: 2
    Dernier message: 24/12/2010, 11h46
  2. [AJAX] Que faire contre les fuites mémoires (memory leaks)
    Par cassy dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 21/08/2007, 16h50
  3. [MFC] A la chasse au memory leak
    Par Yabo dans le forum MFC
    Réponses: 17
    Dernier message: 27/06/2004, 17h35
  4. Réponses: 7
    Dernier message: 26/02/2004, 09h32
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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