2013-02-24 27 views
7

Pochodzę z tła Java, wciąż jestem trochę zdezorientowany co do przydzielania pamięci w C++. Jestem pewien, że pierwsze dwa stwierdzenia są poprawne:C++ Przydzielanie pamięci na stercie i stosie?

void method() { 
    Foo foo; // allocates foo on the stack, and the memory is freed 
       // when the method exits 
} 

void method2() { 
    Foo *foo = new Foo(); // allocates foo on the heap 
    delete foo;    // frees the memory used by foo 
} 

Ale co z czymś takim?

void method3() { 
    Foo foo = *new Foo(); // allocates foo on the heap, and then copies it to the stack? 
          // when the method exits, the stack memory is freed, but the heap memory isn't? 
} 

Say I dodaje foo do globalnej tablicy wewnątrz method3(). Jeśli próbowałem uzyskać dostęp do jednego z elementów danych foo po zakończeniu metody, czy to zadziała? I czy jest method3() podatna na przecieki pamięci?

Z góry dziękuję.

+1

'Foo foo();' faktycznie nie przydziela niczego. Deklaruje funkcję. – chris

Odpowiedz

8
Foo foo(); 

deklaruje funkcję o imieniu foo która zwraca Foo obiektu i nie bierze żadnych argumentów. Jest to najbardziej irytująca analiza w C++. Prawdopodobnie miałeś na myśli:

Foo foo; 

Tworzy obiekt lokalny/automatyczny o rozmiarze foo. Obiekt jest automatycznie deallocated, gdy zakres { }, w którym jest zadeklarowany, kończy się.


Foo *foo = new Foo(); // allocates foo on the heap 
delete foo; 

To prawda, obiekt na freestore wskazanych przez foo jest zwalniane raz zadzwonić delete. Nie ma wycieku pamięci.


Foo foo = *new Foo(); 

alokuje Foo obiekt na freestore a następnie kopię tego obiektu jest używany do inicjacji foo. Ponieważ nie masz wskaźnika do obiektu przydzielonego przez freestore, powoduje to przeciek pamięci. Zauważ, że jeśli destruktor z Foo ma jakiś kod, który wywołuje skutki uboczne, to nie jest to tylko wyciek pamięci, ale niezdefiniowane zachowanie.

+0

Miałem na myśli 'Foo foo()', aby wywołać konstruktor bez argumentów dla klasy 'Foo'. Ale masz rację, zmienię to w pytaniu, aby uniknąć nieporozumień. – nebulabrot

+1

@nebulabrot: 'Foo foo;' robi to, nie 'Foo foo();' –

+0

Dlaczego niezdefiniowane zachowanie, jeśli efekty uboczne są obecne w Foo destructor? Mogę wymyślić kilka przykładów ze złożonym 'Foo', gdzie byłoby dobrze, nawet bez wycieku pamięci! – CygnusX1

Powiązane problemy