2009-01-23 11 views

Odpowiedz

23

Aby przydzielić na stosie, albo zadeklarować swój przedmiot jako zmiennej lokalnej wartością, czy rzeczywiście można korzystają z alloca do uzyskania wskaźnika, a następnie użyć nowego operatora w miejscu:

void *p = alloca(sizeof(Whatever)); 
new (p) Whatever(constructorArguments); 

Jednak podczas korzystania z alloca i na miejscu nowy zapewnia, że ​​pamięć jest zwalniana po powrocie, rezygnujesz z automatycznego wywoływania destruktora. Jeśli próbujesz upewnić się, że pamięć została zwolniona po wyjściu z zakresu, rozważ użycie opcji std::auto_ptr<T> lub innego typu inteligentnego wskaźnika.

12

Jeffrey Hantin jest całkiem poprawny, że możesz użyć nowego miejsca docelowego, aby utworzyć je na stosie z alloca. Ale, poważnie, dlaczego ?! Zamiast tego po prostu wykonaj:

class C { /* ... */ }; 

void func() { 
    C var; 
    C *ptr = &var; 

    // do whatever with ptr 
} 

Masz teraz wskaźnik do obiektu przydzielonego na stosie. I będzie to właściwie zniszczone, gdy twoja funkcja będzie istnieć.

+2

Twój przykład jest dokładnie tym, o czym myślałem, deklarując go jako zmienną lokalną według wartości. –

+0

uwaga: klasa musi mieć pusty konstruktor zdefiniowany w cpp, jeśli masz już zdefiniowany niepusty konstruktor. – kevinf

+0

Przypadku użycia mam - powiedz 'C' ma metoda' wirtualna' zastąpiona w podklasach 'C1' i' C2'. Wtedy mogę chcieć zrobić "C * ptr = criteria? nowy (alloca (sizeof (C1))) C1 (...): new (alloca (sizeof (C2)) C2 (...); ' – rampion

5

Można zrobić:

Whatever* aWhatever = new (alloca(sizeof(Whatever))) Whatever; 

mogłeś wykorzystuje klasę RAII zrobić zniszczenie przypuszczam (EDIT: Zobacz także this other answer for more information on potential problems with this approach):

template <class TYPE> 
class RAII 
    { 
    public: 
     explicit RAII(TYPE* p) : ptr(p) {} 
     ~RAII() { ptr->~TYPE(); } 
     TYPE& operator*() const { return *ptr; } 
    private: 
     TYPE* ptr; 
    } 

void example() 
    { 
    RAII<Whatever> ptr = new (alloca(sizeof(Whatever))) Whatever; 
    } 

Można użyć makra ukryć alloca.

Pozdrowienia DaveF

2

Bądź ostrożny używając _alloca() GCC

GCC ma bug which makes _alloca() incompatible with SJLJ exception handling w C++ (Dwarf2 ocenia się działać poprawnie). Kiedy wyjątek jest wyrzucany z funkcji przydzielania pamięci, błąd powoduje uszkodzenie stosu przed uruchomieniem destruktorów. Oznacza to, że każda klasa RAII pracująca nad przydzielonym obiektem (obiektami) musi wykonać w innej funkcji, aby działała poprawnie. Właściwy sposób wykonania tego wygląda tak:

Powiązane problemy