Quand faut il utiliser new ? - C++ - Programmation
Marsh Posté le 13-04-2012 à 20:02:58
Tu utilises new quand tu fais de l'allocation mémoire sur le tas et non sur la pile.
Tu as 2 manières de déclarer une variable, un tableau ou autre objet primitif: sur le tas, ou sur la pile. Sur la pile, l'objet ne sera plus accessible dès que tu sortiras du scope {...} dans lequel il a été déclaré. Pour ça, il faut déclarer sur le tas. D'autre part, la taille de la pile est limitée, il faut éviter d'y coller bcp de gros objets sous peine de "stack overflow". C'est donc une zone mémoire pour les objets temporaires.
Les objets sur le tas, eux, ont une durée de vie qui s'arrête à l'appel d'un delete ou à la terminaison du programme.
Les free et les delete doivent être rigoureusement appairés sous peine de plantage ou de fuite mémoire. Pour éviter cela, une habitude à prendre dès le début est d'écrire le delete juste après avoir écrit le new, de façon à avoir en tête la durée de vie de l'objet alloué.
Marsh Posté le 13-04-2012 à 20:03:45
Ben oui, enfin tout dépend.
Le problème, c'est que si tu écris ça :
Code :
|
Cette fonction créé un nouveau tableau, qui aura un nombre de cases prit au hasard entre 0 et 79, le soucis c'est qu'une fois ton pointeur retourné, tu n'as aucun moyens d'avoir son nombre de case, sauf si tu le sais d'avance.
Si tu as besoin d'une fonction qui créé un tableau dont tu ne sais pas forcément la taille, j'te conseille plutôt de passer par les std::vector, ou alors une structure du style :
Code :
|
New permet simplement de créer des nouvelles variables dans la mémoire dynamiquement, et renvoit l'adresse où est cette nouvelle variable.
Bon, le soucis, c'est que le C++ est dépourvu de Garbage Collector, ce qui veut dire qu'il faut que tu utilises delete pour supprimer cette nouvelle variable, auquel cas la variable est perdue dans la mémoire.
Petit exemple pour le delete :
Code :
|
Marsh Posté le 13-04-2012 à 20:10:39
Ok, merci beaucoup à vous deux, vos deux réponses sont bien précises et complémentaires !
Marsh Posté le 14-04-2012 à 18:39:51
Terminapor a écrit : New permet simplement de créer des nouvelles variables dans la mémoire dynamiquement, et renvoit l'adresse où est cette nouvelle variable. |
C'est marrant, je trouve que c'est un avantage
Pour en revenir au sujet :
Accessoirement, si tu fais du C++ avec la toute dernière norme, tu ne dois presque jamais utiliser de new. Tu dois à la place passer par des classes qui vont clairement indiquer pour toi la durée de vie de ton objet (unique_ptr, shared_ptr ...).
Marsh Posté le 14-04-2012 à 21:11:31
Tu peux donner un exemple ? J'ai besoin d'un petit raffraichissement...
Marsh Posté le 14-04-2012 à 22:51:51
Mr Sutter explique bien tout ça à 9 min 15 dans la vidéo http://channel9.msdn.com/Events/La [...] rmat=html5
(très bonne vidéo dans l'ensemble d'ailleurs)
Marsh Posté le 14-04-2012 à 23:42:03
theshockwave a écrit : |
Ben oui et non, le soucis c'est que quand on commence, ben on oublie des deletes par-ci par là
Ceci dit, j'ai une question, si on fait plein d'allocs mémoire pas supprimées, l'OS s'en chargera à la fermeture du programme ?
Marsh Posté le 15-04-2012 à 01:28:30
Terminapor a écrit : |
Oui Encore heureux.
Marsh Posté le 15-04-2012 à 11:24:44
Terminapor a écrit : |
De nos jours, oui.
Autrefois (le bon temps de Windows 3.1 par exemple) non.
A+,
Marsh Posté le 15-04-2012 à 14:51:47
Roh, chouette alors, on m'avait dit que justement Windows récupérait super mal la mémoire lorsqu'un log était fermé, mais ça a pas l'air d'actualité
Merki
Marsh Posté le 15-04-2012 à 17:39:27
Terminapor a écrit : Roh, chouette alors, on m'avait dit que justement Windows récupérait super mal la mémoire lorsqu'un log était fermé, mais ça a pas l'air d'actualité |
Si tu veux approfondir, tu pourras te trouver un peu de lecture sur la MMU que tu trouveras dans tout CPU "moderne" et sur l'adressage virtuel des processus (qui fait que tu ne risques pas d'aller malencontreusement perturber le programme d'à côté)
Marsh Posté le 15-04-2012 à 18:04:56
Dans ce cas, comment les types font pour faire des logiciels qui permettent de modifier la mémoire d'un programme ? Techniquement, l'os n'est pas supposé empêcher ça ?
Marsh Posté le 15-04-2012 à 22:09:16
Terminapor a écrit : Dans ce cas, comment les types font pour faire des logiciels qui permettent de modifier la mémoire d'un programme ? Techniquement, l'os n'est pas supposé empêcher ça ? |
Je suppose que tu parles des attaques par shellcode ?
Tu modifies le flot d'instructions du programme lui-même. En gros, quand ton programme s'exécute, le CPU a un pointeur d'instruction qui pointe sur chaque instruction asm à exécuter, un peu à la manière de ce que tu vois quand tu steppes dans un débugger (et exactement ce que tu vois quand tu steppes dans un debugger désassembleur). L'idée est d'exploiter un bug du programme que tu as préalablement repéré (en général un buffer overrun d'un programme C ou C++) avec un désassembleur pour insérer dans le programme monté en RAM un bout de code qui va dévier le pointeur d'instruction vers du code à toi qui fera ce que tu veux. L'OS n'y voit que du feu, il ne peut empêcher que d'écrire dans la heap d'un autre programme, pas la modification du programme lui-même. Un prog C ou C++ peut fonctionner parfaitement et être malgré tout incorrect, et des bugs comme les buffer overruns sont des sources intarrissables d'attaques par les hackers. En particulier, les bugs de ce type sont particulièrement ennuyeux dans les logiciels qui ont un accès privilégié à l'OS parce qu'avec un shellcode, on peut prendre le contrôle de l'OS. Il y a cependant des techniques qui permettent de rendre la tâche considérablement plus difficile, entre autre la "randomisation" d'adresses qui fait que le programme chargé en mémoire n'a jamais le même layout 2 fois de suite et que le programme désassemblé. Cette technique est utilisée par le noyau Linux et Windows 7 en particulier.
Marsh Posté le 15-04-2012 à 23:01:45
Oki, merci de l'info
Marsh Posté le 16-04-2012 à 11:49:56
Non mais y'a pas besoin de faire des bidouilles malsaines pour accéder à la mémoire d'un autre processus, sinon, ce serait une horreur de faire un Debugger. J'imagine qu'il y a une API système pour accéder à la mémoire d'un autre process et en mapper des portions dans l'espace d'adressage local, ca me paraitrait fou sinon.
Marsh Posté le 13-04-2012 à 19:41:19
Bonjour,
j'ai une question toute bête, mais je n'arrive pas à trouver la réponse dans les divers cours de c++ en ligne...
Dans quels cas faut-il utiliser new ?
Par exemple, si une fonction déclare un tableau et le renvoie comme résultat, faut-il utiliser new pour alouer ce tableau ?
Merci !