De toute façon, les systèmes d'exploitation modernes ne peuvent pas gérer les échecs d'allocation ; pour optimiser les performances, ils surengagent généralement la mémoire. Par exemple, si vous appelez malloc()
et demander un gros morceau de mémoire sous Linux, il réussira. même si la mémoire nécessaire pour la sauvegarder n'est pas présente. . Ce n'est que lorsque vous y accédez que le noyau tente réellement d'allouer des pages pour le sauvegarder, et à ce moment-là, il est trop tard pour vous dire que l'allocation a échoué de toute façon.
Donc :
-
Sauf dans des cas particuliers, ne vous inquiétez pas des échecs d'allocation. Si la machine manque de mémoire, c'est un échec catastrophique dont vous ne pouvez pas vous remettre de manière fiable.
-
Néanmoins, il est bon d'attraper les exceptions non gérées et de consigner les informations suivantes e.what()
sortie, puis re- throw
car cela peut être plus informatif qu'un backtrace, et les implémentations typiques des bibliothèques C++ ne le font pas automatiquement pour vous.
-
L'énorme fil de discussion ci-dessus sur le fait que vous ne pouvez pas compter sur un plantage lorsque vous n'avez plus de mémoire est complètement absurde. La norme C(++) ne le garantit peut-être pas, mais sur les systèmes modernes, le plantage est le uniquement une chose sur laquelle vous pouvez compter si vous manquez de mémoire. . En particulier, vous ne pouvez pas compter sur l'obtention d'une NULL
ou toute autre indication de votre allocateur, jusqu'à et y compris une exception C++.
-
Si vous vous trouvez sur un système embarqué où la page zéro est accessible, je vous suggère fortement d'y remédier en mappant une page inaccessible à cet endroit. On ne peut pas compter sur les êtres humains pour vérifier si NULL
des pointeurs partout, mais vous pouvez corriger cela en mappant une page une fois plutôt que d'essayer de corriger tous les problèmes possibles (passés, présents, etc.). et futur) où quelqu'un aurait pu manquer une NULL
.
Je vais nuancer ce qui précède en disant qu'il est possible que vous utilisiez une sorte d'allocateur personnalisé, ou que vous soyez sur un système qui ne fait pas de sur-engagement (les systèmes embarqués sans swap en sont un exemple, mais pas le seul). Dans ce cas, peut-être que vous peut gérer les conditions d'absence de mémoire avec élégance, sur votre système . Mais en général, au XXIe siècle, j'ai bien peur que vous n'en ayez pas l'occasion ; la première fois que vous saurez que votre système n'a plus de mémoire, c'est lorsque les choses commenceront à planter.
8 votes
Avant que j'arrive et que je crie jusqu'à ce que j'obtienne ce que je veux, le magasin où je travaille avait la même convention stupide. Nous avons juste ignoré la réalité. Mon Pariez sur c'est que c'est aussi ce que fait Google.
1 votes
Peu de méthodes de la STL lèvent des exceptions...
15 votes
Google a des normes assez archaïques. Je suppose qu'ils engagent beaucoup d'étudiants et ne peuvent se permettre qu'un petit nombre de magiciens du C++.
1 votes
Dans mon dernier emploi, je me suis fait corriger lors d'une revue de code pour avoir lancé une exception dans un constructeur alors que l'un des paramètres était NULL. Apparemment, l'utilisation de
assert
était une solution acceptable.6 votes
Pas besoin d'affirmer les pointeurs NULL. Il suffit de s'écraser et de brûler. La règle de la réparation : Réparez ce que vous pouvez, mais si vous devez échouer, échouez bruyamment et dès que possible.
21 votes
@Maxim : c'est pour cela que vous devez asserter les pointeurs nuls, pour suivre ce conseil. Si vous n'assertez pas, il y a un risque que votre code puisse échouer de s'écraser et de brûler, parce que le "comportement indéfini" fait pas signifient "segfault immediate". Il s'agit certes d'un petit risque, mais considérez par exemple theregister.co.uk/2009/07/17/linux_kernel_exploit
1 votes
Cartographier une page à l'adresse 0, c'est s'attirer des ennuis. De toute façon, SIGSEGV est suffisant pour moi, je ne peux pas m'embêter avec les assertions pour les pointeurs NULL.
12 votes
@Maxim : "Mapper une page à l'adresse 0, c'est chercher les ennuis." - Tout à fait, et les attaquants cherchent généralement les ennuis lorsqu'ils font un coup malveillant de ce genre. Mais ce n'est qu'un exemple. Si vous agissez comme si vous aviez la garantie d'obtenir un segfault en accédant à un pointeur nul, le compilateur finira par vous surprendre (ou quelqu'un d'autre comme vous) en ne le garantissant pas. Un comportement indéfini peut remonter le temps et faire sortir des démons de votre nez dès le démarrage du programme. Soit vous échouez dès que possible, soit vous ne le faites pas, mais ne vous attendez pas à échouer puis à ne pas échouer.
3 votes
Le temps qu'ils attaquent, ce sera une version sans assertion...
0 votes
Qui n'affirme pas les pointeurs nuls ne vérifie pas les pointeurs nuls.
0 votes
@Etienne de Martel : Parmi elles, il y a des méthodes sans lesquelles vous ne pouvez même pas commencer à utiliser la STL.
0 votes
La seule fois où j'ai vu une plate-forme ne pas planter à cause d'une déréférence de pointeur NULL, c'était une version PowerPC de VxWorks. Le correctif consistait à mapper une page inaccessible à l'adresse 0, ce qui (surprise, surprise), a permis d'attraper un tas de bogues dans le processus. Compter sur les êtres humains pour ajouter des déclarations assert() ou similaires est une manière insensée de s'attaquer à ce problème, et @MaximYegorushkin a tout à fait raison de dire que les exceptions de l'allocateur ne valent pas vraiment la peine qu'on s'en préoccupe (vous pourriez attraper et rapporter, puis terminer, pour sûr, mais ce n'est pas beaucoup mieux que le segfaulting).
0 votes
De plus, s'appuyer sur un argument de sécurité pour soutenir l'idée que l'affirmation est utile est bidon. Si un attaquant peut mapper des pages arbitraires dans votre espace d'adressage, vous avez déjà perdu.
1 votes
Je suis étonné que google n'ait pas un peu honte d'eux-mêmes - allant même jusqu'à rendre ceci (les directives C++ interdisant l'utilisation du C++) librement accessible sur internet. Ne savent-ils pas que l'on peut le googler ? Cela ressemble beaucoup à une idée de gestionnaire -- quelqu'un qui n'a pas écrit un logiciel complexe de toute sa vie ou qui ne se soucie pas d'informer l'appelant de son code de la raison de l'échec.
0 votes
La STL est conçue pour être utilisée sans exception. Ce qui se passe à la place est généralement un crash, ce qui est fondamentalement la même chose que n'importe quelle gestion sûre des exceptions.
0 votes
@MaximEgorushkin Lien réparé :)