53 votes

De nouvelles retourner la valeur NULL dans tous les cas?

Je sais que, conformément à la norme C++ dans le cas où le nouveau ne parvient pas à allouer la mémoire il est censé throw std::bad_alloc exception. Mais j'ai entendu dire que certains compilateurs comme VC6 (ou CRT mise en œuvre?) n'y adhèrent pas. Est-ce vrai ? Je demande cela car le contrôle de la valeur NULL après chaque nouvelle déclaration rend le code look très laid.

57voto

Michael Burr Points 181287

VC6 est non-conforme par défaut à cet égard. VC6 de l' new retourné 0 (ou NULL).

Voici de Microsoft KB Article sur cette question ainsi que leur solution de contournement proposée à l'aide personnalisée new gestionnaire de:

Si vous avez de vieux code qui a été écrit pour VC6 comportement, vous pouvez obtenir le même comportement avec les nouveaux MSVC compilateurs (quelque chose comme 7.0 et versions ultérieures), qui relie en un fichier objet nommé nothrownew.obj. Il y a en fait assez compliqué ensemble de règles dans la 7.0 et 7.1 compilateurs (VS2002 et VS2003) afin de déterminer si elles sont par défaut à non de jeter ou de les jeter new.

Il semble que MS nettoyé ce jusqu' à 8.0 (VS2005)—maintenant, il fait toujours défaut à un lancer de nouveaux à moins que vous donniez un lien vers nothrownew.obj.

Notez que vous pouvez spécifier que vous souhaitez new de rendement 0 au lieu de jeter std::bad_alloc à l'aide de l' std::nothrow paramètre:

SomeType *p = new(std::nothrow) SomeType;

Cela semble fonctionner dans VC6, de sorte qu'il pourrait être une façon plus ou moins mécaniquement corriger le code de travail de même avec tous les compilateurs de sorte que vous n'avez pas à retravailler existants de gestion des erreurs.

9voto

Brian R. Bondy Points 141769

Basé sur le C++ spec, il sera toujours throw std::bad_alloc lorsque vous utilisez simplement le nouveau sans params, mais bien sûr, il peut y avoir certains non-conforme et compilateurs.

Je ne voudrais pas le code pour être en conformité avec non c++ compatible compilateurs bien. VC6 étant l'un d'eux à cet égard.

Il est de bon ton de toujours régler votre pointeur à NULL après que vous les supprimiez. En raison de cette, de la vérification de la valeur NULL est toujours nécessaire.

Cela étant dit, voici quelques options pour le nettoyage de votre code:

Option 1: Configuration de votre propre gestionnaire d'

Un moyen sûr de nettoyer votre code serait d'appeler: set_new_handler premier.

Ensuite, vous pouvez vérifier la valeur NULL dans votre gestionnaire et throw std::bad_alloc il si une valeur NULL est retournée.

Si vous aimez les exceptions mieux, alors c'est votre meilleur pari. Si vous souhaitez retourner la valeur NULL mieux, alors vous pouvez aussi le faire en faisant une capture à l'intérieur de votre nouveau maître.

Option 2: Utilisation de surcharge nouvel

La norme c++ fichier d'en-tête définit une structure nothrow qui est vide. Vous pouvez utiliser un objet de cette structure à l'intérieur de nouveau pour obtenir sa version surchargée qui renvoie toujours NULL.

void* operator new (size_t size, const std::nothrow_t &);
void* operator new[] (void *v, const std::nothrow_t &nt);

Donc, dans votre code:

 char *p = new(std::nothrow) char[1024];

Voici une bonne refrence pour en savoir plus

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X