uso - C++ ¿Cómo asignar memoria dinámicamente en la pila?
reservar memoria con new (7)
¿Hay alguna forma de asignar memoria en la stack lugar de en montón? No puedo encontrar un buen libro sobre esto, ¿alguien aquí tiene una idea?
Como esto está etiquetado como C ++, generalmente declaras los objetos que necesitas en el alcance correcto. Se asignan en la pila y se garantiza que se lanzarán en la salida del alcance. Esto es RAII , y una ventaja crítica de C ++ sobre C. No se malloc
ningún malloc
o new
s, y especialmente no alloca
s.
Cuando / si C ++ permite el uso de valores de const
(no estáticos) para los límites de la matriz, será más fácil.
Por ahora, la mejor manera que conozco es a través de la recursión. Hay todo tipo de trucos inteligentes que se pueden hacer, pero lo más fácil que sé es hacer que tu rutina declare una matriz de tamaño fijo, y llenar y operar lo que tiene. Cuando está hecho, si necesita más espacio para terminar, se llama a sí mismo.
Puede declarar un char[1024]
local char[1024]
o la cantidad de bytes que desee (hasta un punto), luego tome la dirección del local para un puntero a este bloque de memoria en la pila. No es exactamente dinámico, pero podría envolver esta memoria con su propio administrador de memoria si lo desea.
Puede usar la biblioteca BDE C ++, por ej.
const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];
bdlma::BufferedSequentialAllocator allocator(buffer, BUFFER_SIZE);
bsl::vector<int> dataVector(&allocator);
dataVector.resize(50);
BDE proporciona opciones integrales de asignación junto con colecciones como bsl :: vector que pueden usar asignadores polimórficos sin cambiar el tipo de contenedor.
También podrías considerar:
Use alloca()
(a veces llamado _alloca()
o _malloca()
), pero tenga mucho cuidado : libera su memoria cuando sale de una función, no cuando se sale de alcance, por lo que explotará rápidamente si Úselo dentro de un bucle.
Por ejemplo, si tiene una función como
int foo( int nDataSize, int iterations )
{
for ( int i = 0; i < iterations ; ++i )
{
char *bytes = alloca( nDataSize );
// the memory above IS NOT FREED when we pass the brace below!
}
return 0;
} // alloca() memory only gets freed here
Entonces el alloca () asignará un nDataSize bytes adicional cada vez a través del ciclo . Ninguno de los bytes alloca () se libera hasta que regrese de la función. Entonces, si tiene un nDataSize
de 1024 y una iterations
de 8, asignará 8 kilobytes antes de regresar. Si tiene un nDataSize
= 65536 e nDataSize
= 32768, asignará un total de 65536 × 32768 = 2,147,483,648 bytes, casi con toda probabilidad explotando su pila y causando un bloqueo.
anécdota: Usted puede tener problemas fácilmente si escribe más allá del final del búfer, especialmente si pasa el búfer a otra función, y esa subfunción tiene una idea equivocada sobre la longitud del búfer. Una vez solucioné un error bastante divertido en el que estábamos usando alloca()
para crear un almacenamiento temporal para renderizar un glifo de fuente TrueType antes de enviarlo a la memoria de la GPU. Nuestra biblioteca de fuentes no tuvo en cuenta el signo diacrítico en el carácter Å sueco al calcular los tamaños de glifo, por lo que nos dijo que asignara n bytes para almacenar el glifo antes de representarlo, y que en realidad representara n +128 bytes. ¡Los 128 bytes adicionales escribieron en la pila de llamadas, sobrescribiendo la dirección de retorno e induciendo un crash no determinístico realmente doloroso!
Ver _malloca (http://msdn.microsoft.com/en-us/library/5471dc8s(v=VS.100).aspx).
Artículo discutiendo sobre asignación dinámica de memoria
Podemos asignar espacio de longitud variable dinámicamente en la memoria de la pila mediante el uso de la función _alloca. Esta función asigna memoria de la pila de programas. Simplemente toma el número de bytes que se asignará y devolverá vacío * al espacio asignado como una llamada malloc. Esta memoria asignada se liberará automáticamente al salir de la función.
Entonces no necesita ser liberado explícitamente. Hay que tener en cuenta el tamaño de la asignación aquí, ya que puede producirse una excepción de desbordamiento de pila. El manejo de excepción de desbordamiento de pila se puede usar para tales llamadas. En caso de excepción de desbordamiento de pila, se puede usar
_resetstkoflw()
para restaurarla.Entonces nuestro nuevo código con
_alloca
sería:
int NewFunctionA() { char* pszLineBuffer = (char*) _alloca(1024*sizeof(char)); ….. // Program logic …. //no need to free szLineBuffer return 1; }