Juste récemment, j'ai changé la langue de mon projet pour utiliser C++ de C++ avec C, j'ai utilisé Malloc et après que je vérifie si Malloc a été réussi mais avec C++, j'utilise "nouveau" pour allouer la mémoire et je voudrais savoir comment vous Vérifierait normalement l'échec de l'allocation de la mémoire.
De ma recherche Google, j'ai vu rien comme ce qui suit.
char *buf = new (nothrow)char[10];
J'ai aussi vu ce qui suit.
try{} catch(bad_alloc&) {}
Mais qu'en est-il de ce qui suit? J'utilise une partie de chrome routines de bibliothèque pour utiliser des pointeurs intelligents.
Par exemple, j'ai le code comme suit.
scoped_array<char> buf(new char[MAX_BUF]);
C'est génial d'utiliser des pointeurs intelligents mais je ne suis tout simplement pas sûr de savoir comment je devrais vérifier si l'allocation de la mémoire a été réussie. Dois-je vous casser dans deux relevés distincts avec Nothow ou essayer/attraper? Comment faites-vous normalement ces chèques en C++?
Tout conseil sera apprécié.
Eh bien, vous appelez nouveau que vous lancez bad_alloc
, vous devez donc l'attraper:
try
{
scoped_array<char> buf(new char[MAX_BUF]);
...
}
catch(std::bad_alloc&)
{
...
}
ou
scoped_array<char> buf(new(nothrow) char[MAX_BUF]);
if(!buf)
{
//allocation failed
}
Ce que je veux dire par ma réponse, c'est que les pointeurs intelligents propagent des exceptions. Donc, si vous allouez de la mémoire avec une lancée ordinaire, vous devez attraper une exception. Si vous allociez avec une nouvelle nouvelle, vous devez vérifier nullptr
. En tout état de cause, les pointeurs intelligents n'ajoutent rien à cette logique
Je déteste le dire, mais imo, tu vas dans la mauvaise direction (et, malheureusement, les autres réponses que vous avez obtenues ne vous ont pas vraiment signalé dans la bonne direction non plus).
Plutôt que de choisir entre différentes variétés de pointeur intelligent et/ou normales et de variantes NOthow de new
, vous devriez probablement prendre au moins deux autres étapes de ce que vous faites, et Remplacez vos structures de données dynamiques gérées manuellement avec des collections. Cela peut ne pas toujours Soyez le bon choix, mais du moins de mon expérience, c'est la bonne façon d'aller un lot plus souvent que non. La bibliothèque standard présente un certain nombre de possibilités (vecteur, deque, liste, ensemble, etc.), etc.), et que des chances sont plutôt bonnes que vous pouvez utiliser l'un d'entre eux plutôt que de traiter directement avec new
et une entreprise du tout.
Par défaut, ceux-ci utiliseront un allocator qui finit par utiliser la variante normale (lanceur) de new
. Vous voulez donc normalement mettre la plupart des codes dans un bloc de try
à un niveau assez élevé et avoir une clause catch
qui traite d'avoir manqué de mémoire là-bas.
Lorsque/si vous avez besoin de faire face à une mémoire d'allocation directe, des chances sont plutôt bonnes que vous souhaitez toujours fournir une interface similaire à celle des conteneurs standard de la bibliothèque afin que cela fonctionne avec les algorithmes et les itérateurs normaux. Votre expérience initiale utilisant les conteneurs existants va payer de bien lorsque vous arrivez à ce point, même si cela peut être une façade de la route.
En C++, il y a 2 façons principales dans lesquelles new
alloue la mémoire et nécessite chacune une vérification erronée différente.
L'opérateur standard new
lancera un std::bad_alloc
Exception sur l'échec et cela peut être traité comme une exception normale
try {
char* c = new char[100];
} catch (std::bad_alloc&) {
// Handle error
}
Ou alternative la version nothrow
de new
va simplement revenir NULL
sur échec
char* c = new (std::nothrow) char[100];
if (!c) {
// Handle error
}
Je suis curieux de savoir ce que vous attendez de faire lorsque l'allocation échoue? S'il n'y a pas de mémoire disponible pour allouer votre objet, il y a souvent très peu de choses qui peuvent être faites dans le processus.
Vous aurez toujours besoin de vérifier un échec de l'allocation de mémoire.
Soit
scoped_array<char> buf;
try {
buf.reset( new char[MAX_BUF] );
} catch( std::bad_alloc& ) {
// Handle the failure
}
Ou
scoped_array<char> buf( new(std::nothrow)char[MAX_BUF] );
if( buf.get() == NULL ) {
// Handle the failure
}