Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

zarządzanie pamięcią

Ostatnio zmodyfikowano 2011-05-08 18:37
Autor Wiadomość
markon
Temat założony przez niniejszego użytkownika
zarządzanie pamięcią
» 2011-05-07 23:32:42
witam,
mam pewną wątpliwość.
Otóż jeśli mamy jakąś strukturę bądź klasę. Tworzymy obiekt tej klasy - czy musimy wywoływać operator new na jego rzecz, bo na pewno jeśli utworzymy wskaźnik tej struktury/klasy to musimy wywołać operator new)co prawda nie zawsze, w zależności od potrzeb). Czy operator new wywoła konstruktor - w konstruktorze mam różne rzeczy.
Ale pozostaje jeszcze kwestia sprzątania, przecież temu czemu przydzielę pamięć powinienem ją zwolnić za pomocą operatora delete, tylko jak?
mam pisać destruktor? poza tym nie wiem jednej rzeczy przecież jeden wskaźnik może mieć przydzielaną pamięć w czasie programu x razy,
mam potem zwalniać tylko ten jeden wskaźnik? poza tym co z obiektami które nie są wskaźnikami, a ja dla nich nie przydzielałem pamięci operatorem new - musze się martwić o zwalnianie pamięci po nich?
P-32817
DejaVu
» 2011-05-07 23:42:04
C/C++
X * x = new X; //wywoła konstruktor
delete x; //wywoła destruktor

X * x2 =( X * )::malloc( sizeof( X ) ); //nie wywoła konstruktora
::free( x2 ); //nie wywoła destruktora
/edit:
Każdy new musi posiadać delete. Każdy malloc musi posiadać free. Kopiując wskaźniki kopiujesz jedynie adresy. Nie kopiujesz danych. Wskaźników możesz mieć milion wskazujących na ten sam obiekt z danymi. Obiekt istnieje jeden, więc tylko jeden obiekt zwalniasz. Wskaźnik wskazuje na dane, więc jeżeli usuniesz obiekt, to milion pozostałych wskaźników będzie wskazywało na adres w pamięci pod którym nic nie istnieje. Innymi słowy: zwalniasz dane = nie próbujesz odczytywać informacji na które wskazują wskaźniki.
P-32820
markon
Temat założony przez niniejszego użytkownika
» 2011-05-08 16:18:42
jeśli powiedzmy mam pętle for, w niej x razy tworzę wskaźnik na obiekt,
Node *node;
node = new Node;
(w konstruktorze tej struktury mam ustawienie dwóch wskaźników składowych na NULL, ale to chyba nieważne)
Rozumiem, że teraz powinienem tylko raz wywołać delete node;
poza tym nie muszę tworzyć ciała konstruktora, tylko opierać się na domyślnym?
a może napisać destruktor i w nim zamieścić delete node <co będzie lepsze, bo przecież destruktor zostanie automatycznie wywołany po wyjściu z zasięgu > ?
Jeszcze jedno pytanie:
Tworzę wskaźnik na obiekt -OK, ale co jeśli tworzę obiekt normalnie w sensie że Node node; // czy muszę teraz przydzielać pamięć? // martwić się o sprzątanie
P-32851
dmx81
» 2011-05-08 16:48:21
przez new nie tworzysz wskaznikow, ale obiekty.
a wskaznik jedynie zapamietuje ich adresy.
tworzac wielokrotnie nowy obiekt i przypisujac za kazdym razem adres do tego samego wskaznika - gubisz pamiec, poniewaz wskaznik bedzie pamietal tylko ostatni obiekt.
dlatego nalezy stosowac kontenery
C/C++
Node * node;
vector < Node *> v;
for( int i = 0; i < 10; i++ )
{
    node = new Node;
    v.push_back( node );
}

w ten sposob "gromadzisz" wskazniki - a kazdy wskaznik posiada adres nowoutworzonego obiektu. aby dostac sie do obiektu nr 3, uzyjesz

v[2]

ps>> oczywiscie kazdy wskaznik umieszczony w kontenerze trzeba usunac, a dla pewnosci pozniej wektor wyczyscic, aby nie wskazywal "pustych" miejsc

ps2>> tworzac obiekt, nie musisz martwic sie o jego sprzatanie

ps3>> nie jestem pewien, czy dobrze rozumiesz sens uzywania
new
dynamiczne zarzadzanie pamiecia, jak sama nazwa wskazuje, sluzy do zarzadzania pamiecia "na biezaco".
jesli z gory znasz ilosc potrzebnych obiektow, tworzysz sobie te obiekty, nie martwiac sie o ich sprzatanie.

jesli jednak ta liczba jest zalezna od czegos, nie jest stala - wtedy tworzysz wskaznik na obiekt swojej klasy, ktory zajmuje tylko tyle pamieci, ile zajmuje adres (np 32bity=4bajty, podczas gdy obiekt moze zajmowac i 10 x tyle, zalezy od jego budowy).
majac wskaznik na obiekt, nie mozesz jeszcze go uzywac, poniewaz nie wskazuje on na zaden z obiektow. teraz przychodzi kolej na operator [new], zwraca on adres nowego obiektu - co to znaczy? znaczy sie, ze zostaje GDZIES w pamieci przydzielony adres, a "przechwycenie" tego adresu umozliwia przypisanie go do wskaznika wlasnie w momencie tworzenia.
C/C++
Klasa * wsk;
for( int i = 0; i < 3; i++ )
     wsk = new Klasa;

widzisz, co tu jest nie tak?
wskaznik zapamietuje adres obiektu. w jaki sposob dostaniesz sie do adresu pierwszego i drugiego obiektu?
a co gorsza, jak zwolnic pamiec?
P-32852
DejaVu
» 2011-05-08 17:04:04
No jak to nie musi? Jak nie zwolni obiektu to nie wywoła się destruktor. Ponadto zaalokowana pamięć nie będzie oddawana do systemu dopóki aplikacja nie zostanie zakończona.
P-32854
markon
Temat założony przez niniejszego użytkownika
» 2011-05-08 17:05:10
hmm, a jeśli to jest drzewo binarne bądź lista jedno-dwukierunkowa to przecież istnieją wskaźniki które pamiętają adres każdego tworzonego obiektu,
co w tej sytuacji. w jaki sposób zatem zwalnia się pamięć po obiekcie Node node;
P-32855
DejaVu
» 2011-05-08 17:07:52
Lepiej poczytaj jeszcze raz o dynamicznym zarządzaniu pamięcią... a potem spróbuj napisać sobie stos w oparciu o dynamiczne zarządzanie pamięcią.
P-32856
dmx81
» 2011-05-08 17:15:05

No jak to nie musi?

mi chodzilo o brak koniecznosci uzywania delete
C/C++
Klasa k1;
Klasa * k2;
k2 = new Klasa;
delete k2;
 

przeciez nic z k1 w tym przypadku nie musi robic... chyba ze mi sie juz cos pokrecilo?
Nie mowie tu o budowie wewnetrznej obiektu tej klasy,czyli czy w konstruktorze ma jakies inne
new
, bo wtedy analogicznie sprawa wyglada, jak to, o czym tu dyskutujemy - wszytsko utworzone przez new, musi miec delete, a reszta "sama" sie sprzatnie, czyz nie?


Jak nie zwolni obiektu
jak sie zwalnia obiekt?bo ja nigdy tego nie uzywalem

@markon napisal
jeśli tworzę obiekt normalnie w sensie że Node node
Ja na to odpowiadalem - wiec prosze o potwierdzenie, albo o poprawienie mnie, bo do tej pory uwazalem, ze tak utworzonego obiektu nie trzeba jakos recznie zwalniac (poza tym, co dzieje sie w jego konstruktorze), ale przeciez to aplikacja go posprzata?
P-32857
« 1 » 2
  Strona 1 z 2 Następna strona