Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek vysvětluje potřebu a metodu uvolnění objektů, když dojde k výjimce. Témata:
Výjimky vyvolané architekturou nebo vaší aplikací přeruší normální tok programu. Proto je velmi důležité udržet si přehled o objektech, abyste je mohli správně odstranit v případě, že dojde k výjimce.
Existují dvě primární metody, jak to provést.
Zpracujte výjimky místně použitím klíčových slov
tryacatch, poté zničte všechny objekty jedním příkazem.Před vyvolání výjimky mimo blok pro další zpracování zlikvidujte libovolný objekt v
catchbloku.
Tyto dva přístupy jsou znázorněny níže jako řešení pro následující problematický příklad:
void SomeFunc() // Problematic code
{
CPerson* myPerson = new CPerson;
// Do something that might throw an exception.
myPerson->SomeFunc();
// Now destroy the object before exiting.
// If SomeFunc above throws an exception this code will
// not be reached and myPerson will not be deleted.
delete myPerson;
}
Jak je uvedeno výše, myPerson nebude odstraněno, pokud je vyvolána výjimka SomeFunc. Provádění přeskočí přímo na další obslužnou rutinu vnější výjimky, vynechá normální funkci exit a kód, který odstraní objekt. Ukazatel na objekt přejde mimo rozsah, když výjimka opustí funkci a paměť obsazená objektem nebude nikdy obnovena, dokud program běží. Jedná se o únik paměti, pomocí diagnostiky paměti by byl detekován.
Místní zpracování výjimky
Paradigma try/catch poskytuje defenzivní programovací metodu pro zabránění únikům paměti a zajištění, aby objekty byly zničeny, když nastanou výjimky. Příklad uvedený výše v tomto článku se například může přepsat následujícím způsobem:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
// Handle the exception locally
e->Delete();
}
// Now destroy the object before exiting.
delete myPerson;
}
Tento nový příklad nastaví obslužnou rutinu výjimky tak, aby zachytila výjimku a zpracovávala ji místně. Pak funkci normálně ukončí a zničí objekt. Důležitým aspektem tohoto příkladu je to, že se vytvoří kontext pro zachycení výjimky s bloky try/catch . Bez místního rámce výjimky by funkce nikdy nevěděla, že byla vyvolána výjimka a neměla by možnost normálně opustit a zničit objekt.
Vyvolání výjimek po zničení objektů
Dalším způsobem, jak zpracovat výjimky, je předat je do dalšího vnějšího kontextu zpracování výjimek.
catch V bloku můžete vyčistit místně přidělené objekty a pak vyvolat výjimku pro další zpracování.
Vyvolání funkce může nebo nemusí potřebovat uvolnit objekty haldy. Pokud funkce před vrácením v normálním případě vždy uvolní objekt haldy, měla by funkce uvolnit objekt haldy i před tím, než vyvolá výjimku. Na druhou stranu, pokud funkce obvykle neuvolňuje objekt před vrácením za normálních okolností, musíte rozhodnout, zda má být objekt haldy uvolněn.
Následující příklad ukazuje, jak lze místně přidělené objekty vyčistit:
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
e->ReportError();
// Destroy the object before passing exception on.
delete myPerson;
// Throw the exception to the next handler.
throw;
}
// On normal exits, destroy the object.
delete myPerson;
}
Mechanismus výjimky automaticky uvolní rámcové objekty; také je volán destruktor rámcového objektu.
Pokud voláte funkce, které můžou vyvolat výjimky, můžete použít bloky try/catch , abyste měli jistotu, že zachytíte výjimky a máte šanci zničit všechny objekty, které jste vytvořili. Zejména mějte na paměti, že mnoho funkcí MFC může vyvolat výjimky.
Další informace naleznete v tématu Výjimky: Zachytávání a odstraňování výjimek.