2010-05-07 19 views
5
vector<int> vect; 
int *int_ptr = new int(10); 
vect.push_back(*int_ptr); 

Podejrzewam, że po każdym "nowym" musi następować "usuń", ale czy metoda clear() czyści to wspomnienie?C++ Pytanie o przydział pamięci związane z wektorami

Co o tej metodzie robi to samo:

vector<int> vect; 
int int_var = 10; 
vect.push_back(int_var); 

Z tego co rozumiem, jasne() wywołuje zmienne destruktorów, ale oba vect.push_back() metod w tym przykładzie przesunąć obiekt na wektor, a nie wskaźnik. więc czy pierwszy przykład przy użyciu wskaźnika int potrzebuje czegoś innego niż clear() do czyszczenia pamięci?

Odpowiedz

5

Pierwsza metoda przecieka, ponieważ wektor nigdy nie przejmuje własności przydzielonego wskaźnika. W rzeczywistości nie zawiera wskaźnika, a jedynie kopię wartości.

Druga metoda nie wycieka, ponieważ pamięć nie jest dynamicznie przydzielana (z wyjątkiem wewnętrznie w wektorze - sama zajmie się tą pamięcią).

+0

kiedy mówisz, że poradzi sobie z samą pamięcią, masz na myśli, po wywołaniu vector.clear()? – TheFuzz

+0

Pamięć zostanie odzyskana po zniszczeniu wektora. 'clear()' faktycznie nie zwalnia żadnej pamięci; wektor zachowa pojemność na wypadek, gdyby musiał ponownie się rozwijać później. –

+0

Więc co powstrzymuje mnie przed niestosowaniem wskaźników i po prostu tworząc zmienne stosu zmiennych, a następnie wciskając je do wektora, kiedy muszę? z jakiegoś powodu wskaźniki straciły sens. – TheFuzz

5

Po dodaniu , dodajemy kopię danych do wektora. Dlatego w obu przypadkach oryginalne dane muszą zostać zwolnione. W pierwszym przypadku musisz go usunąć; w drugim zostanie "zwolniony" przez wskaźnik stosu, gdy wychodzi poza zasięg.

2

Wektory tworzą kopie na push_back. Ponieważ wskaźnik jest "tylko inną zmienną" (ale taką, która zdarza się wskazywać na pamięć), kiedy push_back jest wskaźnikiem całkowitym, który został wcześniej przydzielony, kopiujesz wartość wskaźnika do wektora, co powoduje potencjalny wskaźnik zwisający, ponieważ być dwoma wskazówkami wskazującymi na to samo miejsce w pamięci.

W pierwszym przykładzie trzeba ręcznie usunąć pamięć. Jedną ze strategii Użyłem w przeszłości za wtrącanie z klas wykres jest mieć coś takiego (ogromne ilości rzeczy redacted powodu bycia w pracy i wpisując szybko):

class graph //quick-format 
{ 
vector<node*> nodes; 
add_node(node n) 
{ 
    node *temp = new node; 
    *temp = n; 
    nodes.push_back(temp) 
} 
~graph() 
{ 
    for(int i = 0; i < nodes.size(); i++) 
     delete nodes[i]; 
} 
}; 

Jako zastrzeżenie, kopia semantyka wykresu będą musiały zostać zbadane. W obecnej wersji spowoduje to usunięcie poprzednio wolnej pamięci. Zaletą jest to, że zawsze możesz mieć ten sam zestaw węzłów. Usterka Emptor, podobnie jak każde użycie pamięci bezpośredniej.

Jednakże, jeśli po prostu wciśniesz zmienną bez wskaźnika, nie ma możliwości wycieku pamięci z twojego końca. Być może wektor wycieknie, ale ... to jest praktycznie niemożliwe w tym momencie dojrzałości narzędzi.