2012-10-09 12 views
17

Załóżmy, że zdefiniowaliśmy klasę tak:rozliczeń wektor wskaźników

class foo { 
private: 
    std::vector< int* > v; 
public: 
    ... 
    void bar1() 
    { 
     for (int i = 0; i < 10; i++) { 
     int *a = new int; 
     v.push_back(a); 
     } 
    }; 

    void bar2() 
    { 
     std::vector<int>::iterator it = v.begin(); 
     for (; it != v.end(); it++) 
     std::cout << (*it); 
     v.clear(); 
    } 
}; 

Krótko mówiąc, odepchnąć pewne wskazówki w wektorze, później wyczyścić wektor. Pytanie brzmi, czy ten kod ma wyciek pamięci? Chodzi mi o to, oczyszczając wektor, czy wskaźniki są właściwie usunięte?

+2

rzeczywiście wcisnąć tylko jeden wskaźnik do wektora; pętla 'for' w' bar1' wykonuje tylko linię 'new int;', ponieważ nie ma nawiasów klamrowych, a 'i +++' jest błędem składni i ... hmm, myślę, że to ma być pseudokod. –

+0

@ Frerich Raabe: edycja ... – mahmood

+0

Trzeba również wektor int wskazówek: 'std :: vector < int* > V;' 'zamiast std :: vector < int > v;' – juanchopanza

Odpowiedz

24

Tak, kod ma wyciek pamięci, chyba że usuniesz wskaźniki. Jeśli klasa foo jest właścicielem wskaźników, to jest odpowiedzialna za ich usunięcie. Powinieneś to zrobić przed usunięciem wektora, w przeciwnym razie stracisz uchwyt do pamięci, którą musisz zwolnić.

for (std::vector<int>::iterator it = v.begin() ; it != v.end(); ++it) 
    { 
    delete (*it); 
    } 
    v.clear(); 

Można uniknąć tego problemu całkowicie zarządzania pamięcią za pomocą std::vector odpowiedniego smart pointer.

+0

czy możesz dać mi metodę straghit (nie smart ptr)? – mahmood

+0

@mahmood To zależy od szczegółów twojej klasy, ale jest to bezpieczny zakład, że powinieneś to zrobić tuż przed oczyszczeniem wektora. Iteruj nad tym, usuwając każdy element. * Następnie * wyczyść to. – juanchopanza

+0

@mahmood Dodałem przykład. – juanchopanza

6

Nie wyczyścisz tylko pamięci wektorowej. Przydzielona pamięć z "nowym" nadal tam jest.

for (int i =0; i< v.size();i++) 
    { 
    delete (v[i]); 
    } 
    v.clear(); 
+0

Jak mogę usunąć? – mahmood

+1

użyj "usuń" w każdej iteracji. Po użyciu wyczyść wektor. e, g delete (* it) –

+0

dla (auto & i: v) { delete (i); } v.clear(); czy ten kod jest poprawny? – lsrawat

2

Można użyć for_each:

std::vector<int*> v; 

template<typename T> 
struct deleter : std::unary_function<const T*, void> 
{ 
    void operator() (const T *ptr) const 
    { 
    delete ptr; 
    } 
}; 

// call deleter for each element , freeing them 
std::for_each (v.begin(), v.end(), deleter<int>()); 
v.clear(); 
+0

Często żałuję, że coś takiego "deletera" nie było łatwo dostępne; Zastanawiam się, czy mógłbyś zaimplementować to pod względem 'std :: mem_fun_ptr lub' std: fun_ptr' lub tak? –

6

myślę najkrótsza i oczywistym rozwiązaniem byłoby:

std::vector<Object*> container = ... ; 
for (Object* obj : container) 
    delete obj; 
container.clear(); 
Powiązane problemy