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 :

Allocation dynamique de mémoire


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 198
    Par défaut Allocation dynamique de mémoire
    Bonjour,

    Ma question s'adresse aux personnes ayant une certaine expérience de développement en C++.

    J'aimerais savoir quelles sont les situations où nous sommes obliger de faire de l'allocation dynamique de la mémoire ? Si nécessaire, utiliser des exemples.

    Merci d'avance,

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    On peut être amené à faire de l'allocation dynamique dans le cas :
    - de factory / clone() / ... : une fonction/méthode retournant un nouvel objet ;
    - stocker des éléments dans un conteneur en conservant le polymorphisme (nécessité de stocker des pointeurs avec la STL) ;
    - avoir une instance qui ne sera pas détruit à la fin du bloc dans lequel il a été déclaré.

    Ma question s'adresse aux personnes ayant une certaine expérience de développement en C++.
    c'est un peu bizarre vu la simplicité apparente de ta question.

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 198
    Par défaut
    Merci pour ta réponse,

    J'ai dit les personnes ayant une certaine expérience car j'aimerais avoir la liste COMPLETE des cas où on est amené à utiliser l'allocation dynamique, bien sûr lorsqu'on est obligé de l'utiliser. En fait, comme la gestion de la mémoire est assez compliquée en C++ (risque de fuite de mémoire), je trouve qu'il est judicieux de n'utiliser l'allocation dynamique de mémoire que lorsque s'est vraiment nécessaire.

    Comme tu as dit, pour cloner un objet, on doit utiliser une allocation dynamique, car sinon, si on utilise une variable locale, elle sera détruite en sortant du block de la fonction.

    Pour les conteneur, je pensais qu'il n'est pas nécessaire d'utiliser d'allocation dynamique : il suffit d'utiliser les conteurs comme vector, ou je me trompe ?

    Merci,

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Le problème, c'est que le vecteur va stocker une copie.
    Ainsi tu ne peux ni stocker des instances de classes non-copiables ni utiliser le polymorphismes (si B hérite de A, tu ne pourras pas stocker des B dans un vecteur de A - enfin en théorie si mais il ne faut surtout pas le faire - ).

    Après, la gestion de la mémoire est très simple en C++ (et surtout par rapport au C).

    Déjà on a :
    - les conteneurs (c'est génial ces petites choses ) ;
    - les pointeurs intelligents ( std::unique_ptr, std::weak_ptr, std::shared_ptr), avec ça "impossible" de faire des fuites mémoires ;
    - des destructeurs pour nos classes ;
    - pas d'horrible garbage collector ;

    Après, il me semble qu'il y a un principe (RAII) pour éviter quelques fuites de mémoires (tu lies une ressource à la durée de vie d'un objet => dès que l'objet est détruit, ta ressource est désallouée ).
    Il y a aussi Valgrind si tu as peur que ton application aie des fuites .

    Après, si dès que tu fais une allocation, tu met directement la désallocation (= j'écris un delete juste après avoir écrit le new), si tu utilise les conteneurs, si tu utilise les pointeurs intelligents, tu devrais éviter une très grande partie des fuites de mémoire

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 198
    Par défaut
    Merci pour ces explications,

    Désolé car j’insiste sur les conteneurs (je débute en C++). Si j'ai bien compris, dans un conteneur comme Vector, c'est une liste d'objets et non pas une liste de pointeurs d'objets, ça veux dire que si j'ajoute un objet à un conteur, cet objet est copié. Donc, il faut créer une conteneur de pointeurs.

    C'est ça ou je suis hors sujet ?

  6. #6
    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
    Citation Envoyé par Neckara Voir le message
    Après, la gestion de la mémoire est très simple en C++ (et surtout par rapport au C).
    Je n'irai pas jusque là, mais plus simple qu'en C, c'est sur.

    Deux autres cas où l'allocation dynamique est utile :
    - utiliser un trop gros objet (ou un grand tableau de taille fixe), -> si il ne tient pas sur la pile il doit être alloué sur le tas (dynamiquement donc).
    - les tableaux de taille variable (ou fixe mais inconnue à la compilation)

    Dans ces deux cas pour des tableaux on utilise généralement des std::vector (ou un autre conteneur adapté) et l'allocation dynamique est cachée à l'intérieur de vector, mais bien présente.
    Pour un gros objet, il faut passer par un new (+smart pointers éventuellement)
    Citation Envoyé par gstratege Voir le message
    Merci pour ces explications,

    Désolé car j’insiste sur les conteneurs (je débute en C++). Si j'ai bien compris, dans un conteneur comme Vector, c'est une liste d'objets et non pas une liste de pointeurs d'objets, ça veux dire que si j'ajoute un objet à un conteur, cet objet est copié. Donc, il faut créer une conteneur de pointeurs.

    C'est ça ou je suis hors sujet ?
    Tout dépend de ton besoin, stocker des copies peut être ce que tu cherches à faire.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Il y a un cas dans lequell'allocation dynamique de la mémoire est indispensable et un cas dans lequel c'est parfois la moins mauvaise solution :

    Lorsque tu veux gérer, dans une seule et même collection des (pointeurs sur des) objets de type dérivés différents.

    Par exemple, si tu as les classes
    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
    class Base{
    public:
     
        virtual ~Base();
    };
    class Derivee1 : public Base{
     
    };
     
    class Derivee2 : public Base{
     
    };
    /* ... */
    class DeriveeN : public Base{
     
    };
    et que tu veux tous les gérer dans une seule et même collection, comme par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    std::vector <Base *> tab;
    /* Notes qu'avec C++11, on préférera utiliser des pointeurs intelligents: */
    std::vector<std::unique_ptr<Base>> tab;
    Dans cette situation, tu n'as, purement et simplement pas le choix : pour profiter du polymorphisme, tu te trouveras face à la nécessité de manipuler tes différents objets au travers de références ou de pointeurs (car, si tu les manipules par valeur, tu sera confronté à un problème appelé "slicing" : seule la partie de la classe de base sera maintenue et la partie correspondant aux classes dérivées sera "oubliée")

    Et comme il est impossible de placer une référence dans une collection... il ne reste plus que le pointeur et donc, l'allocation dynamique

    Le cas dans lequel c'est parfois la moins mauvaise solution est le cas où une de tes variables (que ce soit une variable ou un membre d'une classe) peut ne pas exister et qu'il n'est pas possible de lui donner une valeur "connue pour être invalide".

    Tu devras alors d'office utiliser un pointeur, car il présente la caractéristique, par rapport à une référence, supplémentaire de pouvoir être défini à une valeur connue comme étant invalide : NULL (préférer nullptr en C++11).

    Et, si tu décides d'utiliser un pointeur, tu pourras être confronté à deux situations distinctes:

    Soit l'objet qui va servir de variable "pouvant ne pas exister" est "maintenu" en mémoire par ailleurs, soit c'est la fonction (la classe) qui utilise cette variable qui prend la responsabilité de sa durée de vie.

    Dans le premier cas, tu peux décider "à tout moment" de transmettre "l'adresse mémoire à laquelle se trouve l'objet" qui existe par ailleurs (attention, tu ne devras en aucun cas invoquer delete sur ce pointeur, à moins bien sur que l'objet en question n'ait été créé en utilisant l'allocation dynamique), ou de faire repasser la valeur du pointeur à nullptr.

    Dans le deuxième cas, tu devras utiliser l'allocation dynamique de la mémoire, et tu devras donc veiller invoquer delete sur ton pointeur "en temps opportun", et, en tout état de cause, au plus tard avant de perdre définitivement la possibilité d'accéder à l'adresse représentée par le pointeur.

    Notes encore une fois que les pointeurs intelligents avec lesquels C++11 est arrivé te seront sans doute d'une très grande utilité

    Le gros problème des pointeurs en générale, est, justement, qu'il est souvent difficile de savoir s'il faut invoquer delete dessus ou non, et quand il s'agit de le faire.

    C++11 facilite déjà le problème avec les pointeurs intelligents en permettant de s'assurer qu'il seront de toutes manières détruits en temps opportuns, mais, de manière générale, si tu as le choix entre utiliser une référence et un pointeur, entre le fait d'utiliser un pointeur ou une surcharge de fonction, tu devrais privilégier l'utilisation de la référence ou de la surcharge de fonction à chaque fois que faire se peut, et n'utiliser les pointeurs que lorsque tu n'as vraiment pas le choix .
    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
    Membre très actif
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Octobre 2011
    Messages : 198
    Par défaut
    Merci pour ces remarques pertinentes koala01 !

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

Discussions similaires

  1. probleme d'allocation dynamique de mémoire
    Par Blo0d4x3 dans le forum C
    Réponses: 2
    Dernier message: 13/03/2007, 07h53
  2. Allocation dynamique de mémoire : Limitations ?
    Par rulianf dans le forum C++
    Réponses: 5
    Dernier message: 22/03/2006, 17h03
  3. Allocation dynamique de mémoire
    Par cd090580 dans le forum Autres éditeurs
    Réponses: 7
    Dernier message: 12/11/2005, 11h17
  4. [VC++/ASM] Allocation dynamique de mémoire ?
    Par Magus (Dave) dans le forum x86 32-bits / 64-bits
    Réponses: 7
    Dernier message: 21/12/2004, 15h05
  5. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31

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