Czy istnieje sposób użycia słowa kluczowego new
do przydzielenia na stosie (ala alloca
) zamiast sterty (malloc
)?nowy na stosie zamiast sterty (jak alloca vs malloc)
Wiem, że mógłbym się włamać, ale wolałbym nie.
Czy istnieje sposób użycia słowa kluczowego new
do przydzielenia na stosie (ala alloca
) zamiast sterty (malloc
)?nowy na stosie zamiast sterty (jak alloca vs malloc)
Wiem, że mógłbym się włamać, ale wolałbym nie.
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.
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ć.
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
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:
Twój przykład jest dokładnie tym, o czym myślałem, deklarując go jako zmienną lokalną według wartości. –
uwaga: klasa musi mieć pusty konstruktor zdefiniowany w cpp, jeśli masz już zdefiniowany niepusty konstruktor. – kevinf
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