¿Hay alguna manera de utilizar la palabra clave new
para asignar en la pila (ala alloca
) en lugar de heap (malloc
)?nuevo en la pila en lugar de montón (como alloca vs malloc)
Sé que podría cortar mi propio pero yo preferiría no hacerlo.
¿Hay alguna manera de utilizar la palabra clave new
para asignar en la pila (ala alloca
) en lugar de heap (malloc
)?nuevo en la pila en lugar de montón (como alloca vs malloc)
Sé que podría cortar mi propio pero yo preferiría no hacerlo.
Asignar en la pila, o bien declarar su objeto como una variable local por valor, o en realidad se puede utilizar alloca para obtener un puntero y luego utilizar el nuevo operador en el lugar:
void *p = alloca(sizeof(Whatever));
new (p) Whatever(constructorArguments);
Sin embargo, si utiliza alloca y in-place new garantiza que la memoria se libera al volver, usted renuncia a las llamadas de destrucción automática. Si solo está tratando de asegurarse de que la memoria se libera al salir del alcance, considere usar std::auto_ptr<T>
o algún otro tipo de puntero inteligente.
Jeffrey Hantin tiene bastante razón de que puede usar la colocación nueva para crearla en la pila con alloca. Pero, en serio, ¿por qué? En su lugar, solo haga lo siguiente:
class C { /* ... */ };
void func() {
C var;
C *ptr = &var;
// do whatever with ptr
}
Ahora tiene un puntero a un objeto asignado en la pila. Y, se destruirá adecuadamente cuando exista tu función.
Se podría hacer:
Whatever* aWhatever = new (alloca(sizeof(Whatever))) Whatever;
Usted podría utiliza una clase RAII hacer la destrucción supongo (EDIT: También ver 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;
}
se puede utilizar una macro para ocultar la alloca.
Saludos DaveF
Tenga cuidado al usar _alloca()
con GCC
GCC tiene una bug which makes _alloca()
incompatible with SJLJ exception handling en C++ (Dwarf2 se ha informado que funcionan correctamente). Cuando se descarta una excepción de la función que asigna la memoria, el error causa daños en la pila antes de que se ejecuten los destructores. Esto significa que cualquier clase RAII que trabaje en el (los) objeto (s) asignado (s) tiene que ejecutar en otra función para que funcione correctamente. La forma correcta de hacerlo es así:
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();
}
Su ejemplo es exactamente lo que quise decir al declararlo como una variable local por valor. –
Nota: la clase debe tener un constructor vacío definido en cpp, si ya tiene un constructor no vacío definido. – kevinf
caso de uso que tengo - digamos 'C' tiene un método' virtual' anulado en las subclases 'C1' y' C2'. Entonces es posible que desee hacer 'C * ptr = criterios? nuevo (alloca (sizeof (C1))) C1 (...): nuevo (alloca (sizeof (C2))) C2 (...); ' – rampion