Estructura de un programa en la memoria
La siguiente es la estructura básica de cualquier programa cuando se carga en la memoria.
+--------------------------+
| |
| command line |
| arguments |
| (argc and argv[]) |
| |
+--------------------------+
| Stack |
| (grows-downwards) |
| |
| |
| |
| F R E E |
| S P A C E |
| |
| |
| |
| |
| (grows upwards) Heap |
+--------------------------+
| |
| Initialized data |
| segment |
| |
+--------------------------+
| |
| Initialized to |
| Zero (BSS) |
| |
+--------------------------+
| |
| Program Code |
| |
+--------------------------+
Algunos puntos a tener en cuenta:
- segmento de datos
- segmento de datos inicializados (inicializado a inicializadores explícitos por los programadores)
- segmento de datos sin inicializar (inicializado a segmento de datos cero - NBS [ Bloquear el inicio con el símbolo])
- Segmento de código
- Stack y Heap áreas
segmento de datos
El segmento de datos contiene los datos globales y estáticos que se ha inicializado explícitamente por los usuarios que contienen los valores inicializado.
La otra parte del segmento de datos se llama BSS (debido a que los sistemas anteriores de IBM tenían ese segmento inicializado en cero). Es la parte de la memoria donde el SO inicializa el bloque de memoria a ceros. Así es como los datos globales no inicializados y estáticos obtienen el valor predeterminado como cero. Esta área es fija y tiene un tamaño estático.
El área de datos se divide en dos áreas según la inicialización explícita, ya que las variables que se van a inicializar se pueden inicializar una a una. Sin embargo, las variables que no se inicializan no se deben inicializar explícitamente con 0 de uno en uno. En lugar de eso, el trabajo de inicialización de la variable se deja al sistema operativo.Esta inicialización masiva puede reducir en gran medida el tiempo requerido para cargar el archivo ejecutable.
Principalmente el diseño del segmento de datos está bajo el control del sistema operativo subyacente, aún algunos cargadores dan control parcial a los usuarios. Esta información puede ser útil en aplicaciones tales como sistemas integrados.
Esta área se puede direccionar y acceder usando punteros del código. Las variables automáticas tienen una sobrecarga al inicializar las variables cada vez que son necesarias y se requiere código para hacer esa inicialización. Sin embargo, las variables en el área de datos no tienen una sobrecarga de tiempo de ejecución debido a que la inicialización se realiza solo una vez y también durante el tiempo de carga.
segmento Código
código El programa es el área de código en el código ejecutable está disponible para su ejecución. Esta área también es de tamaño fijo. Solo se puede acceder a estos punteros de función y no a otros punteros de datos. Otra información importante a tener en cuenta aquí es que el sistema puede considerar esta área como área de memoria de solo lectura y cualquier intento de escribir en esta área conduce a un comportamiento indefinido.
Las cadenas constantes se pueden colocar en el código o en el área de datos y eso depende de la implementación.
El intento de escribir en el área de código conduce a un comportamiento indefinido. Por ejemplo (voy a dar solo ejemplos basados en C
) el siguiente código puede ocasionar un error en el tiempo de ejecución o incluso bloquear el sistema.
int main()
{
static int i;
strcpy((char *)main,"something");
printf("%s",main);
if(i++==0)
main();
}
pila y montón áreas
Para la ejecución, el programa utiliza dos partes principales, la pila y montón. Los marcos de pila se crean en pila para funciones y en pila para asignación de memoria dinámica. La pila y el montón son áreas no inicializadas. Por lo tanto, lo que sea que esté allí en la memoria se convierte en el valor inicial (basura) para los objetos creados en ese espacio.
Veamos un programa de ejemplo para mostrar las variables que se almacenan en donde,
int initToZero1;
static float initToZero2;
FILE * initToZero3;
// all are stored in initialized to zero segment(BSS)
double intitialized1 = 20.0;
// stored in initialized data segment
int main()
{
size_t (*fp)(const char *) = strlen;
// fp is an auto variable that is allocated in stack
// but it points to code area where code of strlen() is stored
char *dynamic = (char *)malloc(100);
// dynamic memory allocation, done in heap
int stringLength;
// this is an auto variable that is allocated in stack
static int initToZero4;
// stored in BSS
static int initialized2 = 10;
// stored in initialized data segment
strcpy(dynamic,”something”);
// function call, uses stack
stringLength = fp(dynamic);
// again a function call
}
O considérese un ejemplo todavía más complejo,
// command line arguments may be stored in a separate area
int main(int numOfArgs, char *arguments[])
{
static int i;
// stored in BSS
int (*fp)(int,char **) = main;
// points to code segment
static char *str[] = {"thisFileName","arg1", "arg2",0};
// stored in initialized data segment
while(*arguments)
printf("\n %s",*arguments++);
if(!i++)
fp(3,str);
}
Espero que esto ayude!
Las variables locales no están necesariamente en el marco de la pila; pueden existir solo en los registros, o incluso pueden optimizarse completamente. –
Idealmente, estos son todos los detalles de implementación. Qué implementaciones estás comparando – trashgod
implementaciones estándar Implementación de JDK que implementa Sun/Oracle. y para C/C++ estoy hablando de gcc. –