C++11 éclaircissement sur la gestion de la mémoire - C++ - Programmation
Marsh Posté le 05-10-2014 à 12:48:58
Bonjour, voici un début de réponse.
La première chose à dire est que ton code est du code C++98. Ici C++11 ne change rien
C++ t'autorise à allouer sur la pile (comme dans ton exemple) ou sur le tas (avec new et new []). La "règle" en C++ est la suivante : « celui qui alloue, désalloue ». Une fois que le constructeur et le destructeur (bien souvent, celui généré automatiquement par le compilateur suffit) sont écrits correctement, les types (sémantique de valeur) s'utilisent très simplement, comme int ou std::string (c'est-à-dire sans new et sans delete) et dans ce cas le destructeur est appelé automatiquement à la fin du bloc (pas besoin d'écrire delete) (voir RAII).
Donc oui, si tu utilises std::vector et std::string (sans new) (ou n'importe quel autre type), le destructeur est appelé automatiquement à la fin du bloc (quand le nom de la variable disparaît).
C++11 et C++14 ne déprécie pas new et delete. Ils sont tout simplement devenus inutiles pour la plupart des utilisateurs / développeurs qui vont soit allouer directement sur la pile, soit faire des tableaux avec std::array (C++11) / std::vector, soit allouer sur le tas avec std::make_unique (C++14) (ou std::make_shared (C++11) si la responsabilité de la vie de la ressource doit être partagée).
La fait d'être dans la fonction main ou dans une autre fonction n'influence pas où l'allocation se fait / comment l'allocation doit se faire.
Pour compléter un peu, il existe aussi des types qui ont une sémantique d'entité (j'ai jamais été convaincu par cette sémantique). L'explication précédente ne change pas mais souvent (pas nécessairement) ces types sont alloués sur le tas (dans un std::unique_ptr (C++11) ou un std::vector<std::unique_ptr<T>> ou boost::ptr_vector) pour bénéficier du polymorphisme d'inclusion (héritage publique).
Pour résumer : pour les données membres de tes classes, utilise les types de la bibliothèque standard (int, std::string, std::vector, ...) ; ta classe s'utilisera simplement et tu n'auras pas à te soucier de la gestion de la mémoire ; C++ le fait pour toi grâce au RAII.
Marsh Posté le 05-10-2014 à 13:22:15
Merci pour ces explications détaillées.
Le RAII est une sorte de garbage collector, en somme ?
Spoiler : pas tapé |
Du coup on peut mettre des new partout comme en java des gros cochons ?
Marsh Posté le 05-10-2014 à 14:04:49
Du coup, il n'y a pas besoin de mettre des new partout comme des gros cochons (et comme en Java).
Le RAII est souvent comparé au garbage collector de Java ou C# mais son mécanisme est très différent. Le destructeur d'une variable qui expire à la fin du bloc est appelé automatiquement (à la fin du bloc) (cela est déterministe). Si tu fais un new (sauf s'il est donné à std::unique_ptr en C++11) tu demandes à gérer la mémoire manuellement (et il faudra appeler delete) ; cela ne se fait pas sans une très bonne raison.
Marsh Posté le 05-10-2014 à 12:01:35
Hello,
Dites si dans le constructeur et ou le corps de ma classe, j'utilise des vector et des string, sont-ils détruit automatiquement dans le destructeur par défaut ?
En C++11 les opérateurs new et delete sont-ils devenu obsolète, cad dans l'instanciation ci-dessous l’opérateur new est-il implicite ?
Enfin une dernière question plus général :
Pourquoi les variables local définit dans le main sont sur dans le tas et ceux définit dans les fonctions sont sur la pile ? (Le main n'est il pas une fonction comme les autres, appeler par le système)
Message édité par bqron le 05-10-2014 à 12:03:26