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 :

Fuite mémoire liste doublement chaînée


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 2
    Par défaut Fuite mémoire liste doublement chaînée
    Bonjour,

    Dans le but d'améliorer mon niveau en C++ à l'aide des cours et tutoriels C++, j'ai décider de créer une classe template pour une liste doublement chaînée.

    Après la mise en place de la base du code (init, insertion en fin, ensertion en debut, libération), j'ai voulu tester la présence de fuites mémoires (vu la présence de pointeur, cette option est grandement possible dans mon cas ).

    Voici le code de la classe ci-dessous :

    Liste.h
    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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    template <class TYPE>  class List
    {
    	public : // Constructor-destructor
     
    		List( unsigned long a_ulSize = 0 ) : m_List(NULL)
    		{	Init();	}
     
    		~List()
    		{
    			Clear();
     
    			if( m_List != NULL)
    			{	delete m_List;	m_List = NULL;		}
    		}
     
    	private : // Attributes
    		struct Node
    		{
    			Node( TYPE Data = (TYPE)NULL ) : Data(Data), Prevnode(NULL), Nextnode(NULL)	{}
    			TYPE		Data;
    			Node		*Prevnode;
    			Node		*Nextnode;
    		};	
    		struct Reflist
    		{
    			Reflist() :	Length(0), Tail(NULL), Head(NULL)	{}
    			unsigned long	Length;
    			Node			*Tail;
    			Node			*Head;
    		};
     
    		Reflist		*m_List;
     
    	private : // //Methods
    		void Init()
    		{	m_List = new Reflist;
     
    			if (this->m_List != NULL)
    			{	m_List->Length = 0;
    				m_List->Tail = m_List->Head = NULL;		
    			}
    			return;
    		}
     
    	public : //Methods
    		void PushBack( const TYPE &a_Data = (TYPE) NULL )
    		{
    			if (m_List != NULL) /* si List init */
    			{
    				Node *p_new = new Node(a_Data);
     
    				if (p_new != NULL)
    				{	if ( m_List->Length ) /* Liste vide? */
    					{	m_List->Tail->Nextnode = p_new; 
    						p_new->Prevnode = m_List->Tail; 
    						m_List->Tail = p_new;
    					}
    					else 
    					{	m_List->Head = p_new;		m_List->Tail = p_new; 		}
     
    					m_List->Length++; 
    				}
    			}
    			return;
    		}
     
    		void PushFront( const TYPE &a_Data = (TYPE) NULL )
    		{
    			if (m_List != NULL) /* si List init */
    			{
    				Node *p_new = new Node(a_Data); 
     
    				if (p_new != NULL)
    				{	if ( m_List->Length ) /* Liste vide? */
    					{	m_List->Head->Prevnode = p_new; 
    						p_new->Nextnode = m_List->Head; 
    						m_List->Head = p_new;
    					}
    					else 
    					{	m_List->Head = p_new;		m_List->Tail = p_new; 		}
     
    					m_List->Length++; 
    				}
    			}
    			return;
    		}
     
    		void Clear()
    		{
    			if (m_List != NULL) /* si List init */
    			{
    				Node *p_new; 
    				while(m_List->Head != NULL)
    				{	p_new = m_List->Head;
    					m_List->Head = p_new->Nextnode;
    					delete p_new;	
    				}
     
    				m_List->Tail = NULL;
    				m_List->Length = 0;
    			}
    		}
     
    		void SetSize( const unsigned long &a_ulSize )
    		{
    			while (m_List->Length < a_ulSize )
    				this->PushBack();
     
    			return;
    		}
     
    };

    Pour le test, je reste simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int main(int argc, char** argv)
    {
    	Linkedlist<unsigned int> CWorkingClass;
     
    	for(unsigned int i=0 ; i<1000 ; i++)
    	{
    		CWorkingClass.Resize(1000);
    		CWorkingClass.Clear();
    	}
     
    	return 0;
    }
    En vérifiant avec le "Gestionnaire des tâches Windows", l'occupation mémoire ne retombe pas à sa valeur initiale.

    Deux questions donc pour ceux qui pourraient m'aider:
    - D'où peut venir cette fuite mémoire?
    - Que fais-je de mal dans mon code? (avez vous des conseils afin d'améliorer l'efficacité ou la clarté de mon code?)

    Merci d'avance pour votre aide.

  2. #2
    Membre éprouvé Avatar de alexrtz
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2003
    Messages
    639
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2003
    Messages : 639
    Par défaut
    Citation Envoyé par Melanie_Flower Voir le message
    En vérifiant avec le "Gestionnaire des tâches Windows", l'occupation mémoire ne retombe pas à sa valeur initiale.
    Je ne sais pas si le gestionnaire de tâches est l'outil idéal pour ce genre de détection, mais valgrind ne détecte rien :
    g++ -g -o list list.cc
    valgrind list
    ==20069== Memcheck, a memory error detector
    ==20069== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==20069== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
    ==20069== Command: list
    ==20069==
    ==20069==
    ==20069== HEAP SUMMARY:
    ==20069== in use at exit: 0 bytes in 0 blocks
    ==20069== total heap usage: 1,000,001 allocs, 1,000,001 frees, 24,000,024 bytes allocated
    ==20069==
    ==20069== All heap blocks were freed -- no leaks are possible
    ==20069==
    ==20069== For counts of detected and suppressed errors, rerun with: -v
    ==20069== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Je suis également sceptique quant à l'utilisation du gestionnaire des tâches pour cette mesure .
    Rajoute des push, lance plusieurs fois le programme, et là tu pourras peut-être apercevoir quelque chose via ce biais.
    Mais à priori, le code semble correct, et si Valgrind va en ce sens, c'est un bon départ.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2012
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2012
    Messages : 2
    Par défaut
    Merci beaucoup pour votre aide.

    Je ne connaissais pas Valgrind, le gestionnaire de tâche n'est pas le mieux pour cela en effet mais c'est la seule idée que j'ai eu .

    Contente de savoir qu'au final tout va bien! A part ce problème de fuite mémoire (qui au final n'en est pas un), y'a t-il des conseils sur la façon de coder?


    Encore merci

  5. #5
    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
    Si tu mets en place des tests unitaires (ce qui est recommandé, surtout sur ce genre de classes), il y a des chances que le framework de tests unitaire active les fonctionnalités du compilateur pour détecter des fuites mémoire (c'est par exemple le cas de boost.test avec visual C++)
    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.

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 21/03/2008, 22h46
  2. Réponses: 9
    Dernier message: 14/01/2007, 17h09
  3. Listes doublement chaînées
    Par nicolas66 dans le forum C++
    Réponses: 5
    Dernier message: 19/11/2005, 12h17
  4. Liste doublement chaînée
    Par garf dans le forum Langage
    Réponses: 3
    Dernier message: 27/09/2005, 09h33

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