¿Cómo se gestionan, implementan y asignan las memorias de stack y stack?

En C / C ++ podemos almacenar variables, funciones, funciones de miembros, instancias de una clase en una stack o en un montón.

¿Cómo se implementa cada uno? ¿Cómo se gestiona (alto nivel)? ¿GCC preasigna una porción de memoria para ser utilizada para la stack y el montón, y luego se distribuye bajo petición? ¿La memoria original proviene de la RAM?

¿Se puede asignar una función en el montón en lugar de una stack?

Aclaración

Realmente estoy preguntando sobre la implementación y la administración de las memorias de montón y stack. Después de leer la pregunta referida, no encontré nada que aborde eso … gracias por el enlace

Los sistemas operativos modernos no le dan acceso directo a la RAM del hardware y, en su lugar, la resumen en la llamada memoria virtual, que se asigna a la memoria RAM a pedido. Cada proceso generalmente recibe su propia copia privada del espacio completo de direcciones. Esto permite que el sistema operativo mueva la memoria de un proceso en la RAM en tiempo de ejecución o incluso la cambie al disco. Esto ocurre de forma transparente, es decir, un proceso no se notifica de dicha reubicación y no necesita tener código para manejarlo. (Algunas aplicaciones en tiempo real pueden usar técnicas para evitar que su memoria se cancele).

Al vincular archivos de objeto a un archivo ejecutable o una biblioteca dinámica, el vinculador asigna de forma estática memoria para las instrucciones de la CPU de una función / método y para todas las variables globales. Cuando el sistema operativo carga la biblioteca ejecutable o dinámica, asigna esta memoria preasignada a la memoria real.

Al inicio, cada hilo recibe un área de memoria privada llamada stack. Cada vez que llamas a una función / método, el comstackdor inserta código para asignar automáticamente (incrementando el puntero de la stack) suficiente memoria de la stack para contener todos los parámetros, variables locales y el valor de retorno (si existe) que utiliza la función / método. Si el comstackdor determina que es suficiente dejar algunas variables en los registros del procesador, no asigna memoria en la stack para ello. Cuando la función / método retorna, ejecuta el código generado por el comstackdor para liberar (al decrementar el puntero de la stack) esta memoria. Tenga en cuenta que los destructores de cualquier objeto en la stack se invocarán cuando el bloque se definan en las salidas, lo que puede tardar mucho antes de regresar. Además, el comstackdor puede reutilizar la memoria distribuida como lo considere oportuno.

Cuando se lanza una excepción, el comstackdor del comstackdor inserta un código especial que conoce el diseño de la stack y que puede desenrollarlo hasta encontrar un controlador de excepciones adecuado.

A diferencia de esto, la memoria en el montón se asigna usando new / delete , para lo cual el comstackdor inserta el código para solicitar o liberar memoria usando una biblioteca del sistema.

Tenga en cuenta que esta es una descripción simplificada para darle una idea de cómo funciona la asignación de memoria.

Básicamente, el comstackdor no implementa el heap, sino que lo hace la biblioteca C runtime. Obviamente, este código depende de la plataforma. En los sistemas tipo Unix o Unix, la implementación generalmente se basa en la llamada al sistema sbrk / brk y se asigna una mayor cantidad de memoria para reducir el número de llamadas al sistema. Esta memoria es luego administrada por el administrador de memoria de montón. Si se requiere más memoria, se emite una nueva llamada a sbrk. La dirección final actual del montón se puede obtener con sbrk (0) si está interesado en depurar las rutinas de administración del montón. La mayoría de los administradores de memoria no devuelven la memoria al sistema operativo durante la vida útil de un proceso (la biblioteca de tiempo de ejecución de gnu c sí cumple ciertas restricciones).

Una descripción más detallada está disponible en http://gee.cs.oswego.edu/dl/html/malloc.html .