キーワードを使用して、ヒープ()の代わりにnew
スタック(ala)に割り当てる方法はありますか?alloca
malloc
私は自分自身をハックできることを知っていますが、むしろしたくありません。
キーワードを使用して、ヒープ()の代わりにnew
スタック(ala)に割り当てる方法はありますか?alloca
malloc
私は自分自身をハックできることを知っていますが、むしろしたくありません。
スタックに割り当てるには、オブジェクトをvalueでローカル変数として宣言するか、実際に alloca を使用してポインターを取得し、その場で new 演算子を使用します。
void *p = alloca(sizeof(Whatever));
new (p) Whatever(constructorArguments);
ただし、alloca と in-place new を使用すると、戻り時にメモリが解放されることが保証されますが、自動デストラクタの呼び出しは放棄されます。スコープからの終了時にメモリが確実に解放されるようにするだけの場合は、std::auto_ptr<T>
またはその他のスマート ポインター型の使用を検討してください。
Jeffrey Hantin は、placement new を使用して alloca を使用してスタック上に作成できることは非常に正しいです。しかし、真剣に、なぜですか?代わりに、次のようにします。
class C { /* ... */ };
void func() {
C var;
C *ptr = &var;
// do whatever with ptr
}
これで、スタックに割り当てられたオブジェクトへのポインターができました。そして、関数が存在する場合は適切に破棄されます。
あなたがすることができます:
Whatever* aWhatever = new ( alloca(sizeof(Whatever)) ) Whatever;
RAII クラスを使用して、私が推測する破壊を行うことができます (編集:このアプローチの潜在的な問題の詳細については、この他の回答も参照してください):
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;
}
マクロを使用して alloca を非表示にすることができます。
よろしく DaveF
_alloca()
GCC で使用する場合の注意事項
GCC にはバグがあり、C++ での_alloca()
SJLJ 例外処理と互換性がありません(Dwarf2 は正しく動作することが報告されています)。メモリを割り当てる関数から例外がスローされると、デストラクタが実行される前にバグがスタックの破損を引き起こします。これは、割り当てられたオブジェクトで動作するすべての RAII クラスが、適切に動作するために別の関数で実行する必要があることを意味します。適切な方法は次のようになります。
void AllocateAndDoSomething()
{
Foo* pFoo = reinterpret_cast<Foo*>(_alloca(sizeof(Foo)));
new (pFoo) Foo;
// WARNING: This will not work correctly!
// ScopedDestructor autoDestroy(pFoo);
// pFoo->DoSomething();
// Instead, do like this:
DoSomething(pFoo);
}
void DoSomething(Foo* pFoo)
{
// Here, destruction will take place in a different call frame, where problems
// with _alloca() automatic management do not occur.
ScopedDestructor autoDestroy(pFoo);
pFoo->DoSomething();
}