Comme d'autres l'ont noté, ce que vous voulez attraper est std::bad_alloc
. Vous pouvez également utiliser catch(...)
o catch(exception& ex)
pour attraper n'importe quelle exception ; ce dernier permet de lire les données de l'exception et de les utiliser dans le gestionnaire d'exception.
Mark Ransom avait déjà fait remarquer que lorsque le programme ne peut plus allouer de mémoire, même l'impression d'un message d'erreur peut échouer. Considérons le programme suivant :
#include <iostream>
using namespace std;
int main() {
unsigned long long i = 0;
try {
while(true) {
// Leaks memory on each iteration as there is no matching delete
int* a = new int;
i++;
}
} catch(bad_alloc& ex) {
cerr << sizeof(int) * i << " bytes: Out of memory!";
cin.get();
exit(1);
}
return 0; // Unreachable
}
( Je recommande vivement que le programme soit compilé en 32 bits pour éviter que le système ne manque de mémoire sur une machine 64 bits. Les programmes 32 bits ne peuvent pas allouer plus de 4 Go de mémoire, ou 2 Go par défaut sous Windows. )
Lorsque le premier bad_alloc
est jeté dans l'infini while
le contrôle est transmis à la boucle catch
mais le programme échoue toujours avec une exception non gérée. Pourquoi ? Un autre site bad_alloc
est jeté dans le gestionnaire d'exception en essayant d'imprimer sur cerr
. Vous pouvez le vérifier en utilisant un débogueur : Définissez un point d'arrêt à l'emplacement catch(bad_alloc& ex)
exécutez le programme dans le débogueur, puis parcourez chaque instruction une fois que vous avez atteint le point d'arrêt. A bad_alloc
L'exception sera déclenchée dans le cerr
déclaration.
Ainsi, pour gérer correctement un scénario de dépassement de mémoire, vous devez réserver un peu de mémoire afin de pouvoir imprimer un message d'erreur avant de quitter. Sinon, le programme se bloquera sur une exception non gérée alors qu'il tente d'imprimer le message d'erreur. Pour ce faire, vous pouvez allouer un bloc de mémoire qui sera désalloué dans le gestionnaire d'exception, comme le suggère Mark Ransom :
// Reserve 16K of memory that can be deleted just in case we run out of memory
char* _emergencyMemory = new char[16384];
// ...
try {
// ...
} catch(bad_alloc& ex) {
// Delete the reserved memory so we can print an error message before exiting
delete[] _emergencyMemory;
cerr << sizeof(int) * i << " bytes: Out of memory!";
cin.get();
exit(1);
}
//...