2009-01-23 5 views

Répondre

23

Allouer sur la pile, soit Déclarez votre objet comme une variable locale en valeur, ou vous pouvez réellement utiliser alloca pour obtenir un pointeur, puis utilisez le en place nouvel opérateur:

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

Cependant, si vous utilisez alloca et in-place new pour vous assurer que la mémoire est libérée au retour, vous abandonnez l'appel automatique de destructeur. Si vous essayez simplement de vous assurer que la mémoire est libérée à la sortie de la portée, pensez à utiliser std::auto_ptr<T> ou un autre type de pointeur intelligent.

12

Jeffrey Hantin a raison de dire que vous pouvez utiliser placement new pour le créer sur la pile avec alloca. Mais, sérieusement, pourquoi ?! Au lieu de cela, faites simplement:

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

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

    // do whatever with ptr 
} 

Vous avez maintenant un pointeur vers un objet alloué sur la pile. Et, il sera correctement détruit quand votre fonction existe.

+2

Votre exemple est exactement ce que je voulais dire en le déclarant comme une variable locale par valeur. –

+0

note: la classe doit avoir un constructeur vide défini dans cpp, si vous avez déjà un constructeur non-vide défini. – kevinf

+0

cas d'utilisation que j'ai - disons que 'C' a une méthode' virtual' surchargée dans les sous-classes 'C1' et' C2'. Ensuite, je peux vouloir faire 'C * ptr = critères? new (alloca (sizeof (C1))) C1 (...): nouveau (alloca (sizeof (C2))) C2 (...); ' – rampion

5

Vous pouvez faire:

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

Vous pourriez utilise une classe RAII pour faire la destruction, je suppose (EDIT: Voir aussi 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; 
    } 

Vous pouvez utiliser une macro pour cacher la alloca.

Cordialement DaveF

2

Soyez prudent lorsque vous utilisez _alloca() avec GCC

GCC a un bug which makes _alloca() incompatible with SJLJ exception handling en C++ (DWARF2 est rapporté fonctionne correctement). Lorsqu'une exception est expulsée de la fonction allouant la mémoire, le bogue provoque une corruption de la pile avant que les destructeurs ne puissent s'exécuter. Cela signifie que toute classe RAII travaillant sur le (s) objet (s) alloué (s) doit exécuter dans une autre fonction pour fonctionner correctement. La manière correcte de le faire ressemble à ceci:

Questions connexes