Jest to ćwiczenie z C++ Primer, rozdział 18:sposobów, aby uniknąć wycieku pamięci, gdy wyjątek rzucone
void exercise(int *b, int *e)
{
vector<int> v(b, e);
int *p = new int[v.size()];
ifstream in("ints");
// exception occurs here
}
Powyższy kod mogłoby spowodować wyciek pamięci, ponieważ pamięć uda nam bezpośrednio (tj p
) nie jest automatycznie zwolniony, gdy wystąpi wyjątek.
Ćwiczenie 18.3:
Istnieją dwa sposoby, aby prawidłowo poprzednią pracę kodu, jeśli jest wyjątek. Opisz je i zastosuj.
Wiem, że możemy użyć inteligentnego wskaźnika, aby uniknąć tej pułapki:
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
}
czyli
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
}
Nie jestem pewien, czy to są TWO
sposoby. W końcu są one praktycznie takie same. Więc pomyślałem o inny sposób:
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.
}
Jeśli wystąpi wyjątek, rzucać p
zainicjować innego wskaźnika, a także usunąć ten jeden. Wiem, że to nie jest doskonałe rozwiązanie, ponieważ mogą wystąpić inne wyjątki, więc nie mam nawet szansy na wyrzucenie p
. Ale nie mogę wymyślić lepszego. Czy możesz pomóc znaleźć drugą drogę?
Co powiesz na prosty try-catch dla wszystkiego ('...') w ramach funkcji? Usuń i przeprowadź tam ponownie. ... A może użyć wektora dla 'p'? – deviantfan
O tak, 'rethrow' jest znacznie lepszy dla tego problemu. Dziękuję Ci! – chihyang
Zapominasz 'wektora p (v.size());' –