Ben oui.
Sauf sous les vieux Visual.
C'est pour ça que je conseille plutôt maintenant:
Et là ou ça semble le plus approprié, mettre le try/catch(std::bad_alloc const &)...Code:
1
2
3
4 CObjet* pObjet = new CObjet(); CHECK_NEW(pObjet); //TO FILL
Version imprimable
Ben oui.
Sauf sous les vieux Visual.
C'est pour ça que je conseille plutôt maintenant:
Et là ou ça semble le plus approprié, mettre le try/catch(std::bad_alloc const &)...Code:
1
2
3
4 CObjet* pObjet = new CObjet(); CHECK_NEW(pObjet); //TO FILL
OK
Je dois donc réajuster tous mes codes à partir de maintenant! Quelle erreur de ma part d'avoir cru à un vieil article verifiant juste que c'est pas NULL
En fait, j'utilise VISUAL 2003
Si tu utilises 2003, commence par faire le test avec la classe BigRaiiAlloc, pour vérifier le comportement.
J'ai testé la classe BigRaiiAlloc avec mon VS2003, std::cout << "L'operateur new a retourne NULL!" << std::endl; ne s'est jamais exécuté ... mais ce code plante ma machine mais bon ...
Je retiens donc que ça ne retourne jamais NULL sauf dans le cas de ce bug http://support.microsoft.com/kb/167733/fr où il faut créer son propre gestionnaire
Exécute-le dans le debugger avec un breakpoint sur la ligne en question.
Sous VC++ 6, j'ai bien droit à un affichage en règle de "L'operateur new a retourne NULL!", aussi bien en Debug qu'en Release.
Et oui ça ne s'affiche jamais mais de même aussi pour std::cout << "L'operateur new a lance une exception." << std::endl;
Revenons aussi à un code que vous avez posté ici
Je n'ai pas besoin de assert( m_pSubEntityTypesToLoad == 0 );, c'est facultatif?Code:
1
2
3
4
5
6
7
8
9
10
11
12 else { assert( m_pSubEntityTypesToLoad == 0 ); m_pSubEntityTypesToLoad = new CSubEntityTypesToLoad(); std::auto_ptr<CSubEntityTypeToLoad> spSETConnectedSemiEquipments( new CSubEntityTypeToLoad(enEProcessSETConnectedSemiEquipments, NULL) ); std::auto_ptr<CSubEntityTypeToLoad> spSETEquProductFamilies( new CSubEntityTypeToLoad(enEProcessSETEquProductFamilies, NULL) ); m_pSubEntityTypesToLoad->push_back( spSETConnectedSemiEquipments.get() ); spSETConnectedSemiEquipments.release(); m_pSubEntityTypesToLoad->push_back( spSETEquProductFamilies.get() ); spSETEquProductFamilies.release(); }
Pour m_pSubEntityTypesToLoad = new CSubEntityTypesToLoad();
Donc, en gros j'ai pu retenir de ce fil que si ça se passe mal, il peut y avoir memory leak même s'il y a delete m_pSubEntityTypesToLoad au destructeur, pour cela j'ai à faire aux macros:
Code:
1
2
3 #define CHECK_NEW_NAME_(x) obj_check_new_ ## x #define CHECK_NEW_NAME(x) CHECK_NEW_NAME_(x) #define CHECK_NEW(p) CheckNew CHECK_NEW_NAME(__LINE__)(p)
L'assertion, c'est jusqe pour vérifier que le pointeur ne pointe pas déjà sur un truc, car l'écraser avec une nouvelle valeur serait sûrement une fuite de mémoire.
Quant aux macros, elles ne suffisent pas, il faut la classe CheckNew en plus.
C'était juste pour limiter le message! :PCitation:
Quant aux macros, elles ne suffisent pas, il faut la classe CheckNew en plus.
L'assertion, c'est jusqe pour vérifier que le pointeur ne pointe pas déjà sur un truc, car l'écraser avec une nouvelle valeur serait sûrement une fuite de mémoire.
Tu maitrises très bien les leaks!!! :king:
Qu'est ce que j'ajouterais en plus? Merci, un bon programmeur C++ doit savoir éviter les memory leaks