¿Es posible liberar memoria asignada por alloca() de C explícitamente, antes de que la función actual salga? ¿Si es así, cómo?Liberación de la memoria asignada aloca
Respuesta
Es posible, pero no hay una función escrita previamente para hacerlo. Tendría que profundizar en la implementación de alloca() de su compilador para descubrir qué está haciendo y luego escribir su propia freea(). Como cada compilador realiza alloca() de manera diferente, debe volver a escribir su freea() para cada compilador.
Pero me parece difícil de creer que valga la pena el problema. Simplemente use malloc/free si necesita liberarlo explícitamente; esas funciones suelen estar muy optimizadas. Aproveche de ellos.
Una implementación portátil es "void freea (void * p) {} // Just fake it". – paxdiablo
Um, no. no puede mover el puntero de pila sin dañarlo, y no puede reubicar elementos en la pila porque sus direcciones pueden almacenarse en otro lugar. La razón del trabajo libre/malloc es que tienen control total de su espacio de almacenamiento dinámico. – SquareCog
Implementé alloca(), y sí, puedes hacer un freea(). No se trasladarán los elementos más de lo que alloca() lo hace: los locales con su dirección tomada son necesariamente antes del espacio asignado. No debe dejar punteros colgantes en el espacio libre de todos modos, como tampoco puede hacerlo en el espacio libre. –
No, porque está asignado en la pila junto con las variables locales. Si desea memoria que pueda liberar explícitamente, use una de las funciones de asignación de memoria dinámica.
No hay ningún híbrido que le permita liberar explícitamente Y tenerlo automáticamente libre al salir de la función también, al menos no en el estándar.
Está asignando en la pila con alloca(); Si algo más sucedió después (y no puedes controlarlo sin escribir todo en el ensamblaje), no puedes simplemente reducir la pila. Entonces, hasta que abandones el marco de pila de tu función, esto es imposible.
Esta es también la razón por la que realmente puede ensuciar las cosas si desborda el búfer asignado. Puede comenzar a sobrescribir las direcciones de código a las que su función vuelve, haciendo que salte en otro lugar, todo tipo de cosas horribles. ¡Ten cuidado!
Malloc funciona en el montón, por eso es mucho más flexible en lo que puede hacer.
De http://www.gnu.org/software/libc/manual/html_mono/libc.html#Variable-Size-Automatic:
La asignación de un bloque con
alloca
es una acción explícita; puede asignar tantos bloques como desee y calcular el tamaño en tiempo de ejecución. Pero todos los bloques se liberan cuando sale de la función desde la que se llamó a alloca, como si fueran variables automáticas declaradas en esa función. No hay forma de liberar el espacio explícitamente.
Esto sería útil para el estilo de paso de continuación (CPS), en lugar de una realloca.
Podría llamar a una función que asignó y manipuló una cadena en la parte superior de la pila, antes de reducir la pila a la longitud de la cadena y llamar a la siguiente función.
No hay ninguna razón conceptual por la que no podría haber un freea(), que sería un nop para cualquier cosa que no sea la entrada más alta en la pila.
Usando C99 puede lograr lo mismo usando Variable Length Array. Simplemente declare el VLA en un nuevo alcance; se liberará automáticamente cuando se cierre el alcance.
Por ejemplo:
int some_function(int n) {
// n has the desired length of the array
...
{ // new scope
int arr[n]; // instead of int *arr = alloca(n*sizeof(int));
// do stuff with array
}
// function continues with arr deallocated
...
}
Sí, pero depende de la implementación de alloca(). Una implementación razonable y simple de alloca() es que el bloque recién asignado se colocó en en la parte superior de la pila ajustando el puntero de la pila.Por lo tanto para liberar esta memoria sólo tenemos que hacer un negativo asignación (pero hay que estudiar la aplicación real de alloca()), vamos a verificar que mediante la adopción de la no portátil siguiente código de ejemplo:
#include <stdio.h>
#include <alloca.h>
int main()
{
unsigned long p0, p1, p2;
p0=(unsigned long)alloca(0);
p1=(unsigned long)alloca((size_t) 0x1000);
p2=(unsigned long)alloca((size_t)-0x1000);
printf("p0=%lX, p1=%lX, p2=%lX\n", p0, p1, p2);
return 0;
}
en una máquina x64 edad con sonido metálico 2.9, una salida de muestra es:
p0=7FFF2C75B89F, p1=7FFF2C75A89F, p2=7FFF2C75B89F
por lo que sabemos de la aplicación no validar el argumento -0x1 000, de lo contrario, el valor sin signo será un entero muy grande. El puntero de pila originalmente era 0x ... B89F; ya que esta pila crece hacia arriba alloca (0x1000) por lo tanto, cambie el puntero de la pila hasta a (0x ... B89F - 0x1000) = 0x ... A89F. Después de la asignación negativa (0xA89F - (-0x1000)) el puntero de pila volvió a 0x ... B89F.
Sin embargo, con gcc 4.8.3, un ejemplo de salida es:
p0=7FFFA3E27A90, p1=7FFFA3E26A80, p2=7FFFA3E27A70
En /usr/include/alloca.h encontramos:
#ifdef __GNUC__
# define alloca(size) __builtin_alloca (size)
#endif /* GCC. */
por lo que sabemos que la orden interna alloca La función proporcionada por gcc 4.8.3 hizo algo similar, excepto que asignó 0x10 bytes adicionales como margen de seguridad. Al hacer una asignación negativa, aún asume que crece hacia arriba y, por lo tanto, intentó reservar 0x10 bytes adicionales (- 0x10) así que p2 = 0x ... 6A80 - (-0x1000) - 0x10 = 0x ... 7A70. Por lo tanto, ten mucho cuidado.
- 1. Three.js - memoria de liberación
- 2. Vista de memoria asignada
- 3. Android - obtener memoria asignada
- 4. C++ memoria asignada dinámicamente
- 5. inicialización de la memoria asignada con stackalloc
- 6. aumentar la memoria asignada a la aplicación
- 7. FastMM: Total de memoria asignada
- 8. Implementación de aloca
- 9. interactuando sobre la memoria asignada con Marshal.AllocHGlobal()
- 10. ¿C# limpia la memoria asignada C++?
- 11. Liberar memoria asignada con newCString
- 12. Java utilizando más memoria que la memoria asignada
- 13. C# picturebox liberación de memoria problema
- 14. iPhone Gestión de memoria y liberación
- 15. Determinar el tamaño de la memoria asignada dinámicamente en C
- 16. ¿La primitiva tiene asignada una dirección de memoria?
- 17. Uso de realloc para reducir la memoria asignada
- 18. Memoria asignada: algoritmos parcialmente basados en disco
- 19. Memoria libre asignada en una función diferente?
- 20. Malloc -> ¿cuánta memoria ha sido asignada?
- 21. Liberar memoria asignada en una DLL diferente
- 22. ¿Cómo liberar memoria asignada usando mmap?
- 23. Manejo de la memoria asignada Archivo en C# directamente desde la memoria
- 24. ¿Puede Win32 "mover" la memoria asignada en el montón?
- 25. ¿la memoria asignada por kmalloc() se libera automáticamente?
- 26. Cómo poner a cero la memoria asignada por Marshal.AllocHGlobal?
- 27. ¿Por qué la memoria no asignada está marcada como 0xCC?
- 28. Seguridad de los hilos con el montón de memoria asignada
- 29. Desarrollo de iPhone - problema de liberación de memoria
- 30. memoria asignada gratuito antes de vuelta una función
¿Podría explicar su motivación? ¿Por qué querrías liberar el espacio asignado antes de volver? – Motti