2010-08-15 18 views
5

Ho una domanda per quanto riguarda la memoria e deallocazione eccezioni. quando uso delete per eliminare un oggetto creato sull'heap. Se si verifica un'eccezione prima di questa eliminazione, la memoria sta per perdere o questa eliminazione verrà eseguita?memoria deallocazione e le eccezioni

+0

Vuoi dire prima, non durante? Bene, allora è ovvio che se il 'delete' non viene chiamato (perché prima viene lanciata un'eccezione), non viene liberata alcuna memoria. Se ti stai chiedendo d'eccezione durante la distruzione, quindi http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3 – adf88

risposta

3

Questo dipende da dove quel delete è. Se è all'interno dello catch che rileva l'eccezione, potrebbe essere richiamato.

try { 
    f(); // throws 
} catch(...) { 
    delete p; // will delete 
} 

Se è dopo il catch che rileva l'eccezione e che catch non restituisce dalla funzione (cioè consente flusso di esecuzione procedere dopo il blocco catch) allora il delete potrebbero essere definiti.

try { 
    f(); // throws 
} catch(...) { 
    // execution proceeds beyond catch 
} 
delete p; // will delete 

Se il delete non è in un blocco catch o dopo un blocco catch che permette l'esecuzione di procedere poi alla delete non chiamerà.

try { 
    f(); // throws 
    delete p; // will not delete 
} // ... 

Come si può immaginare, nei due primi casi al di sopra del delete non verrà richiamato se c'è un lancio prima della delete:

try { 
    f(); // throws 
} catch(...) { 
    g(); // throws 
    delete p; // will not delete 
} 
+1

Nota che le eccezioni sono buone, perché non si deve prendere loro in ogni funzione nello stack di chiamate. Possono essere combattuti su un livello "esterno". Come liberate la memoria allocata all'interno delle funzioni interne? Ad esempio, se la funzione f() che genera un'eccezione alloca memoria. Sarebbe una buona idea catturare l'eccezione all'interno di f() e liberare memoria e quindi rilasciarla al livello successivo nello stack delle chiamate? – NickSoft

2

Non sarà chiamato. Ecco perché sei incoraggiato a guardare RAII. Vedere Stroustrup

5

Nel caso che lei descrive, la memoria sta per perdere.

Due trucchi per evitare questo problema:

  • uso puntatori intelligenti, che non soffrono dello stesso problema (soluzione preferita)
    -> il puntatore intelligente nel costruito in pila, la sua distruttore è quindi chiamata, non importa cosa, e la cancellazione del contenuto punta è previsto nel distruttore

  • dichiarazioni uso try/catch, ed eliminare l'oggetto in catch così

0

Dobbiamo anche fare in modo che "eccezione" significa davvero eccezione C++ che può essere catturata da try/catch. Esistono anche altre eccezioni nel sistema che C++ try/catch non può intercettare (ad es. Divisione per 0).

In questi casi (oltre lo scopo degli standard C++), anche "delete" non verrà eseguito a meno che queste eccezioni non vengano intercettate e il gestore richiami esplicitamente "delete" in modo appropriato.

Problemi correlati