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 :

Delete et fuite de mémoire


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Points : 61
    Points
    61
    Par défaut Delete et fuite de mémoire
    Bonjour, j'ai appris que pour éviter les fuites de mémoire, il faut appelé delete pour chaque pointeurs alloué afin de libérer la mémoire.

    Mais supposons que dans un programme j'ai une classe client et que je créé chaque client dynamiquement à la demande de l'usagé au fur et à mesure et que je les places dans un vecteur.

    1) Vaut-il mieux que je créé un vecteur de pointeur Client ou bien un vecteur de Client ? Dans le cas des pointeurs de Client je devrais faire un delete sur chaque pointeurs du vecteur dans une boucle lors de la fermeture du programme.

    Mais dans le cas ou c'est un vecteur de client comment je libère la mémoire ?

    2) Étant donné que le libère la mémoire lorsque l'usagé choisis de quitter le programme, que se passe-t-il si il ferme le programme sans passer par la fonction quitter ? La mémoire ne sera pas libéré ou si windows fait ça tout seul ?

    Merci

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par AsmCode
    1) Vaut-il mieux que je créé un vecteur de pointeur Client ou bien un vecteur de Client ? Dans le cas des pointeurs de Client je devrais faire un delete sur chaque pointeurs du vecteur dans une boucle lors de la fermeture du programme.
    Si tu n'as pas besoin que la durée de vie de ton objet client soit supérieure à la portée dans laquelle il est déclaré et si tu n'as pas besoin de fonction virtuelles dans la classe client, le vecteur de pointeur ne présente pas vraiment d'intéret.

    Citation Envoyé par AsmCode
    Mais dans le cas ou c'est un vecteur de client comment je libère la mémoire ?
    Les opérations qui suppriment des éléments du vecteur appellent les destructeurs des objets contenus, donc tu n'as rien à faire, c'est automatique.

    Citation Envoyé par AsmCode
    2) Étant donné que le libère la mémoire lorsque l'usagé choisis de quitter le programme, que se passe-t-il si il ferme le programme sans passer par la fonction quitter ? La mémoire ne sera pas libéré ou si windows fait ça tout seul ?
    Toute la mémoire occuppée par un processus est libérée à la sortie de celui-ci.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Points : 61
    Points
    61
    Par défaut
    Ok

    Mais si mon vecteur est dans une routine ou une fonction, même si ce ne sont pas des pointeurs vers des objets clients, ce vecteur étant accessible ailleurs si je le passe en parametre ou si je le déclare global alors quelle est la différence si j'ai un vecteur de pointeurs ?

    Que se passe-t-il si j'efface un vecteur de pointeurs ? seul les pointeurs seront perdu et les emplacements mémoire des objets clients ne seront pas libérés ?

    Comment se fait-il qu'en faisant un delete sur un pointeur il apelle le desctructeur ? En fait qu'est-ce qui libère la mémoire ? Pas le destructeur, car il n'y a rien dedans et puis le pointeur n'est qu'une variable qui contient une adresse. C++ libère aussitôt la mémoire pointé et appelle le destructeur de l'objet (au cas ou) des trucs seraient à faire pour cet objet mais qui dans la plupart du temps ne fait rien ?

    De plus quelle est la différence entre delete et delete[] ? Dans quel contexte utiliser l'un ou l'autre ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    258
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 258
    Points : 307
    Points
    307
    Par défaut
    Citation Envoyé par AsmCode
    Ok
    Mais si mon vecteur est dans une routine ou une fonction, même si ce ne sont pas des pointeurs vers des objets clients, ce vecteur étant accessible ailleurs si je le passe en parametre ou si je le déclare global alors quelle est la différence si j'ai un vecteur de pointeurs ?
    C'est plus propre pour l'allocation et la désallocation.

    Citation Envoyé par AsmCode
    Que se passe-t-il si j'efface un vecteur de pointeurs ? seul les pointeurs seront perdu et les emplacements mémoire des objets clients ne seront pas libérés ?
    Exactement. Les destructeurs des objets stockés sont appelés, et le destructeur d'un pointeur ne détruit pas l'objet pointé.

    Citation Envoyé par AsmCode
    Comment se fait-il qu'en faisant un delete sur un pointeur il apelle le desctructeur ?
    C'est la définition du comportement de delete

    Citation Envoyé par AsmCode
    En fait qu'est-ce qui libère la mémoire ? Pas le destructeur, car il n'y a rien dedans et puis le pointeur n'est qu'une variable qui contient une adresse. C++ libère aussitôt la mémoire pointé et appelle le destructeur de l'objet (au cas ou) des trucs seraient à faire pour cet objet mais qui dans la plupart du temps ne fait rien ?
    Lorsqu'un objet est détruit, son destructeur est appelé ainsi que le destructeur de chacun des membres.

    Citation Envoyé par AsmCode
    De plus quelle est la différence entre delete et delete[] ? Dans quel contexte utiliser l'un ou l'autre ?
    delete[] est à utiliser quand tu fais un new T[n] pour allouer un tableau, sinon delete.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Points : 61
    Points
    61
    Par défaut
    Ok je comprends mieux maintenant

    Par contre je me demandais l'utilité de faire un delete puisque le OS libère la mémoire de toute façon ? Car d'après ce que j'ai compris si l'usager ferme le programme de force en tuant le processus par exemple, alors le delete n'est pas fait puisque ce delete est applé lorsque l'usager appuie sur la touche pour quitter le programme dans le menu principal. Si le OS ne libère pas la mémoire tout seul alors il y a une fuite inévitable ?

    Aussi je me demandais quoique un peu HS pour ce topic, lorsqu'on fait

    string s;

    cin >> s;

    s peut-être de combien de long maximum ?

  6. #6
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    Avril 2005
    Messages
    4 155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 4 155
    Points : 6 486
    Points
    6 486
    Par défaut
    Par contre je me demandais l'utilité de faire un delete puisque le OS libère la mémoire de toute façon ?

    Déjà d'un point de vue de la qualité de code, c'est obligatoire. Ensuite, rien ne dis que le système va libérer la mémoire. Enfin, il est courrant que dans les applications, la somme de la mémoire à allouer (pour tout le programme) dépasse la mémoire disponible, par conséquent si tu ne désalloue pas ce dont tu n'as plus besoin, tu vas faire planter le programme (au mieux tu vas le faire ralentir et tout le système avec).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    string s;
     
    cin >> s;
     
    s peut-être de combien de long maximum ?
    A priori, je dirai la taille d'un size_t moins quelques bytes. En général ça va dépasser la capacité mémoire.

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 625
    Points : 30 671
    Points
    30 671
    Par défaut
    Salut,

    new fait en fait trois choses:
    • Il alloue un espace mémoire correspondant à sizeof(l'objet à créer)
    • Il place les différents membres dans la mémoire (et la vtable, s'il échoit)
    • Il appelle le constructeur afin d'initialiser les différents membre (et donc les constructeurs des différents membres, s'il échoit)


    delete va faire exactement l'inverse:
    • appeler le destructeur (et donc les destructeurs des différents membres, s'il échoit)
    • libérer la mémoire (pas besoin de "non placer" les membres )

    Du moins, ce sont les comportements tels qu'il sont définis par défaut... car tu peux, comme tout opérateur, décider de les surcharger

    La différence entre new et new[] et entre delete et delete[], c'est que le premier (new ou delete) alloue ou libère la mémoire pour un objet unique, alors que le deuxième (new[] ou delete[]) permet l'allocation (et la libération) de la mémoire pour un nombre donné d'objets...

    Il faut savoir que, s'il est possible d'utiliser delete[] avec new, il est impossible d'utiliser delete avec new[] et que, dans tous les cas, il est largement préférable d'utiliser delete avec new et delete[] avec new[]

    De manière générale, et quel que soit le conteneur que tu envisage (list, vector, ou autre), si tous les objets sont strictement du meme type (objet n'aurait ni classe parente, ni classe dérivée) ou que tu n'envisage pas de le caster en un objet d'un autre type (il y a peut etre une classe ojetderivee, mais tu peux te contenter du comportement d'objet), il est préférable d'utiliser un conteneur d'objet...

    Si, par contre, tu prévois d'utiliser le polymorphisme ou que tu as besoin d'un conteneur pouvant contenir plusieurs types d'objets différents (mais dérivant tous d'une meme classe de base), il semblera plus judicieux de te tourner vers un conteneur de pointeur sur objets...

    De manière générale, il y a deux principes qu'il faut toujours garder en tete quand on programme (il y en a plus, mais ceux là sont la base de tout ) :
    • La solution la plus simple est toujours la moins compliquée... heu... je veux dire la meilleure
    • Il ne sert à rien de maintenir en mémoire une information dont tu n'as plus besoin...La mémoire utilisée pour cette information finira toujours, un jour ou l'autre, par etre nécessaire ailleurs ... meme si les quantités de mémoire disponible atteignent des sommets

    Comme il est quand meme plus simple de se contenter d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    vecteur.push_back(objet);
    //ou 
    vecteur.clear();
    plutot que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    vector.push_back(new objet);
    //ou
    for(unsigned int i=0;i<vecteur.size();i++)
        delete vecteur[i];
    vecteur.clear();
    et ceci quelle que puisse-t-être la méthode d'insertion ou de suppression, et quel que puisse-t-être le conteneur , le premier principe de base que je viens de t'énoncer t'incitera à utiliser un conteneur d'objets aussi longtemps qu'il ne sera pas prouvé que tu as besoin d'un conteneur de pointeurs d'objets
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par PRomu@ld
    Déjà d'un point de vue de la qualité de code, c'est obligatoire.
    C'est une chose très courante pour nombre de programmes, certes, mais il y a quelques exceptions. Par exemple, pour des utilitaires au temps d'exécution court, qui ne restent pas longtemps en mémoire, ça peut être une optimisation de laisser l'OS tout libérer en bloc à la fin, au lieu de libérer petits bouts par petits bouts.

    Comme toute optimisation de ce genre, ce n'est à faire AMA que quand le programme marche déjà correctement, et qu'on peut mesurer si l'optimisation fait vraiment gagner du temps ou pas.
    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.

Discussions similaires

  1. new/delete/cast, fuite de mémoire ou pas ?
    Par boli_971 dans le forum C++
    Réponses: 7
    Dernier message: 18/04/2009, 13h40
  2. Réponses: 1
    Dernier message: 02/12/2005, 14h18
  3. fuite de mémoire
    Par mamag dans le forum MFC
    Réponses: 17
    Dernier message: 19/08/2005, 10h42
  4. Fuite de mémoire en utilisant le template list
    Par schtroumpf_farceur dans le forum Langage
    Réponses: 9
    Dernier message: 18/07/2005, 20h44
  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