Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 15:02, 10 January 2008.

Pilha de limpeza - Cleanup Stack

From Forum Nokia Wiki

Memória é um recurso limitado em dispositivos móveis e para que o sistema possa ser executado por um longo período sem a necessidade de re-boots é necessário que partes da memória não seja perdidas durante a execução de um aplicação. A CleanupStack foi criada para impedir que áreas de memória sejam perdidas (memory leak) durante um abandono.

Quando um abandono ocorre em uma função (seja lançado por ela ou por uma função que esteja sendo executada), todas as variáveis automáticas são destruídas incluindo ponteiros. Apesar do ponteiro ser destruído, o espaço de memória para onde ele aponta não é liberado, nesta situação temos um vazamento de memória pois a referência à um determinado espaço de memória foi perdida, isto ocorre mesmo quando um abandono é capturado por uma TRAP.

A função da CleanupStack é liberar os recursos alocados na heap por ponteiros locais que estejam em funções que abandonaram. Na ocorrência de um abandono os ponteiros que estiverem na pilha de limpeza terão suas memória desalocadas.

Considere o exemplo:

void FuncAbandonaL()
{
         CMinhaClasse* pt = new CMinhaClasse(); // desconsiderando a construção em duas fases
         pt->ExecutarFuncL(); // função que pode abandonar
        delete pt; 
}

Caso ExecutarFuncL(); abandone, tudo que estiver na pilha da função FuncAbandonaL() até o momento do abandono será destruído, incluindo o ponteiro pt. Porém a instrução delete pt nunca será executada pois ExecutarFuncL() não obteve sucesso na sua execução. Teremos um vazamento de memória por parte de pt.
Exemplo correto utilizando a CleanupStack

void FuncAbandonaL()
{
         CMinhaClasse* pt = new CMinhaClasse(); // desconsiderando a construção em duas fases
         CleanupStack::PushL(pt); // pt está libre de vazamento de memória , a CleanupStack irá se encarregar dele
         pt->ExecutarFuncL(); // função que pode abandonar
         CleanupStack::PopAndDestroy(); // Método de CleanupStack que libera o ponteiro da pilha e remove seus recursos
}

Uma pilha faz parte da CleanupStack, ponteiros locais são adicionados a ela a medida que passam por áreas de código com risco de abandono. Assim como qualquer pilha, métodos Push e Pop são utilizados para adicionar e remover elementos à pilha.




Contents

PushL

Para adicionar elementos à pilha é utilizado o método PushL(). Este método possui três sobrecargas são elas:

CleanupStack::PushL(CBase* aPtr);
CleanupStack::PushL(TAny* aPtr);
CleanupStack::PushL(TCleanupItem);

Cada um destes irá executar uma operação de limpeza apropriada na ocorrência de um abandono ou em uma chamada ao método CleanupStack::PopAndDestroy().






CleanupStack::PushL(CBase* aPtr);

Um ponteiro de CBase é recebido como argumento deste método, como conveção de idiomas do Symbian , todas as classes derivadas de CBase devem ser alocadas na heap e possuem um destrutor virtual. Na ocorrência de um abandono o destrutor da classe será chamado e a área de memória ocupada pelo objeto será liberada. Como o destrutor de CBase é virtual, isto garante que deletar um ponteiro de CBase* tendo como referência uma classe derivada desta a deleção será da classe mais derivada para a menos derivada até o destrutor não implementado de CBase.

CleanupStack::PushL(TAny* aPtr);

Qualquer classe que não for derivada de CBase entra neste caso. Em certas situações , algumas classes não possuem destrutores, segundo a conveção de idiomas do SymbianOS , estas classes são conhecidas como T Class. Caso estas sejam alocadas na heap e referenciadas por ponteiros locais, ao coloca-los na pilha de limpeza este método será chamado. Caso um abandono ocorra a pilha de limpeza irá apenas liberar a memória utilizada pelo objeto sem chamar seu destrutor.

CleanupStack::PushL(TCleanupItem);

Pop e PopAndDestroy

Ponteiros só devem permanacer na pilha de limpeza enquanto estiverem em áreas do código com risco de abandono, após isto devem ser liberados da pilha. Para liberar um ponteiro da pilha basta chamar o método CleanupStack::Pop() , ele irá remover da pilha o elemento que estiver no seu topo. Deve-se ter cuidado ao realizar esta operação para se ter a certeza de estar removendo o elemento correto. É possível passar o ponteiro que deseja liberar da pilha como argumento de Pop() , será verificado se ele está no topo da pilha, caso não, um panic será lançado. Esta verificação é realizada apenas na versão de debug e não compromete a performance na versão release da aplicação. Uma outra forma de verificar se um determinado ponteiro está no topo da pilha é com o método CleanupStack::Check(TAny* aExpectedItem ) porém este método realiza a verificação nas versões debug e release de sua aplicação.


Outro método para liberar um elemento da pilha é o CleanupStack::PopAndDestroy() , além de liberar o elemento da pilha ele desaloca os recursos alocados por ele.
 

Outros métodos para limpeza

Outros métodos especiais são oferecidos para realizar operações de limpeza específicas. Estes métodos são parametrizados (template) para receber qualquer tipo de classe. Tais métodos são utilizados para adicionar elementos a CleanupStack , estes elementos devem ser removidos normalmente com CleanupStack::Pop() ou CleanupStack::PopAndDestroy().

CleanupClosePushL(T& aRef)

Na ocorrência de um abandono ou de uma chamada a CleanupStack::PopAndDestroy() o método Close() de T é chamado. Este método é muito utilizado em classes R que liberam seus recursos no método Close().

CleanupDeletePushL(T& aRef)

Na ocorrência de um abandono ou de uma chamada a CleanupStack::PopAndDestroy() o objeto é destruído com uma chamada ao operador delete. Semelhante ao método PushL(CBase* aPtr) porém funciona com classes que não são derivadas de CBase.

Referência

Symbian Os Explained - Effective C Programming For Smartphones. Stichbury, Jo. Editora John Wiley & Sons 2005.

Related Discussions
Thread Thread Starter Forum Replies Last Post
奇怪的问题,app里不出现异常,exe文件里就会:( test_008 Symbian 9 2008-08-06 03:53
Problem with Thread and Active Object paipeng General Symbian C++ 1 2007-03-13 19:47
how many cleanupstacks can one thread have? xhsoldier General Symbian C++ 2 2006-08-07 15:25
Program stops at PushL mg_at_uni General Symbian C++ 5 2008-03-17 10:21
cleanupstack sandy_zeng General Symbian C++ 5 2007-08-08 17:57
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX