Questo è un esercizio da C++ Primer, capitolo 18:modi per evitare perdita di memoria quando eccezione generata
void exercise(int *b, int *e)
{
vector<int> v(b, e);
int *p = new int[v.size()];
ifstream in("ints");
// exception occurs here
}
Il codice di cui sopra potrebbe causare perdita di memoria, perché la memoria gestiamo direttamente (cioè p
) non è automaticamente liberato quando si verifica un'eccezione.
Esercizio 18.3:
Ci sono due modi per rendere il lavoro precedente codice correttamente se viene generata un'eccezione. Descrivili e implementali.
So che possiamo usare puntatore intelligente per evitare questa trappola:
void exercise(int *b, int *e)
{
vector<int> v(b, e);
unique_ptr<int[]> p(new int[v.size()]);
ifstream in("ints");
// exception occurs here
}
o:
void exercise(int *b, int *e)
{
vector<int> v(b, e);
shared_ptr<int> p(new int[v.size()], [](int *p){ delete[] p; });
ifstream in("ints");
// exception occurs here
}
non sono sicuro se queste sono TWO
modi. Dopotutto, sono praticamente gli stessi. Così ho pensato ad un altro modo:
void exercise(int *b, int *e)
{
vector<int> v(b, e);
int *p = new int[v.size()];
ifstream in("ints");
// exception occurs here
if(!in)
throw p;
}
// caller
try {
exercise(b, e);
} catch (int *err) {
delete[] err; // initialize err with b and delete e.
}
Se si verifica un'eccezione, gettare p
per inizializzare un altro puntatore ed eliminare quello. So che questa non è una soluzione perfetta, perché potrebbero verificarsi altre eccezioni in modo che io non abbia nemmeno la possibilità di lanciare p
. Ma non riesco a pensarne uno migliore. Potresti aiutare a trovare il secondo modo?
Che ne dici di un semplice try-catch per tutto ('...') all'interno della funzione? Elimina e rilancia lì. ... Oppure, che ne dici di usare un vettore anche per 'p'? – deviantfan
Oh, sì, 'rethrow' è molto meglio per questo problema. Grazie! – chihyang
Stai dimenticando 'vector p (v.size());' –