2017-01-19 3 views
1

Lors de l'utilisation de nouvelles et une exception bad_alloc est levée. Avez-vous encore besoin d'appeler delete sur le ptr avant de poursuivre ou pouvez-vous être sûr qu'aucune mémoire n'a été allouée?Lors de la mauvaise erreur d'allocation du nouveau, delete doit-il encore être appelé?

Que diriez-vous si vous utilisez la version nothrow? pouvez-vous à nouveau être sûr qu'aucune mémoire n'a été allouée si un nullptr est retourné?

+0

De quel "ptr" parlez-vous? Publiez du code. –

+0

tout ptr qui est alloué de la mémoire via nouveau –

+0

Post. Certains. Code. La première partie de la question est sans réponse comme écrite, et borderline absurde. Quand 'new' est lancé, l'évaluation de l'expression ne s'est pas terminée. –

Répondre

2

Lorsqu'une exception est levée, vous ne « continuez » - l'exécution saute au gestionnaire de capture.

Dans une expression comme:

p = new int; 

la sous-expression new int est évaluée en premier. Si cela déclenche une exception, l'exécution n'atteint pas l'affectation. p conserve la valeur précédente (le cas échéant).

Dans le cas p = new(std::nothrow) int;, si l'allocation échoue, p deviendra null. Il n'a aucun effet pour appeler delete sur un pointeur null.

+0

Non c'est pas. Vous avez répondu. Je vous demandais si vous pouviez avoir la certitude qu'aucune affectation n'avait eu lieu et/ou qu'aucun souvenir n'avait été alloué. –

2

La version nothrow de new ne signale en effet des erreurs en retournant un pointeur NULL, auquel cas aucune mémoire a été allouée et aucun objet n'a été construit:

T * p = new (std::nothrow) T(a, b, c); 

if (p) 
{ 
    // stuff 
} 

delete p; // OK, works on null pointers, too. 

Ou peut-être:

if (T * p = new (std::nothrow) T(a, b, c)) 
{ 
    // stuff 
    delete p; 
} 
else 
{ 
    // allocation failure 
} 

Ou encore mieux:

if (std::unique_ptr<T> p(new (std::nothrow) T(a, b, c))) 
{ 
    // stuff 
} 

la dernière version supprime automatiquement la objet dynamique sur toute sortie du bloc if, qui est un exemple typique de la manière dont C++ gère plusieurs sorties et donc localise la complexité.

(Peut-être qu'il devrait y avoir un modèle de fonction make_unique_or_null pour encapsuler ce dernier bit.)

+1

Bien sûr, le deuxième exemple a le problème de fuite de mémoire si '// stuff' peut lancer –

+0

@ M.M: Le premier exemple a aussi ce problème. Je suppose que vous connaissez généralement le besoin d'un code d'exception correct. –

+1

Ouais, je pense que ce serait bien si votre réponse mentionne ceci à un moment donné au cas où il n'est pas clair pour le débutant quel est l'avantage de la dernière version –