Analice la diferencia entre la asignación de memoria de pila y de montón
En el ámbito informático, la pila es un concepto que no se puede ignorar y se utiliza básicamente en los programas en C que escribimos. Pero para muchos principiantes, el concepto de pila es muy vago. Pila: una estructura de datos, que es un lugar utilizado para el almacenamiento cuando el programa se está ejecutando. Esta puede ser la comprensión de muchos principiantes, porque yo también lo pensaba y se confundía con la palabra pila en lenguaje ensamblador. Algunos de mis amigos a mi alrededor han conocido a muchos amigos que no saben cómo hablar en pila cuando programan y publican en línea, por lo que creo que es necesario compartir mis puntos de vista sobre la pila con ustedes. Si me equivoco, no duden en hacerlo. para iluminarme Esto será útil para todos. El estudio será de gran ayuda.
Pila y montón en estructuras de datos
En primer lugar, es necesario conocer la pila en la estructura de datos. Aunque lo llamamos así, la pila son en realidad dos estructuras de datos: montón. y apilar.
El montón y la pila son estructuras de datos en las que los elementos de datos se organizan de manera ordenada.
El montón es como un depósito de datos o un cuadro de datos
Comenzaremos con la pila familiar, que es una estructura de datos con una naturaleza de último en entrar, primero en salir, es decir Es decir, lo primero que se almacena es lo primero que se saca, y lo primero que se almacena es lo último que se saca. Esto es como si queremos sacar el objeto debajo de la caja (el objeto en el frente), primero debemos sacar el objeto encima de la caja (el objeto en la parte posterior).
Un montón es como un árbol al revés
A diferencia de un montón, un montón es una estructura de datos de árbol ordenada en la que cada nodo tiene un valor. Por lo general, cuando nos referimos a la estructura de datos del montón, nos referimos al montón binario. La característica de un montón es que el nodo raíz tiene el valor más pequeño (o más grande), y los dos subárboles del nodo raíz también son montones. Debido a esta característica del montón, el montón se utiliza a menudo para implementar colas de prioridad. El acceso al montón es arbitrario. Esto es como recoger libros de la estantería de una biblioteca. Cualquiera de los libros no tiene que ser como una pila, primero saca todos los libros que tiene enfrente, este mecanismo de la estantería es diferente al de la caja, podemos sacar directamente los libros que queramos.
Montón y pila en la asignación de memoria
Sin embargo, este no es el punto. Lo que quiero decir con montón y pila no es el montón y la pila de estructuras de datos. La razón por la que hablo del montón y la pila de estructuras de datos es para distinguirlas de las áreas del montón y la pila de las que hablaré más adelante, así que asegúrese de tenerlo en cuenta.
Lo siguiente trata sobre la asignación de memoria del montón y la pila en programas en lenguaje C. No creo que sea detallado en términos generales, el programa se almacena en Rom o Flash. y debe ejecutarse durante la operación. Cópielo en la memoria para su ejecución. Se almacenará información diferente en la memoria, de la siguiente manera:
La dirección del área de la pila en la memoria es relativamente alta. de es la dirección de la pila. Si la dirección de crecimiento es hacia arriba, la dirección de la pila crece hacia abajo.
La pila asigna espacio para variables locales y el área del montón crece hacia arriba para asignar el espacio de memoria requerido por el programador. Además, hay un área estática para asignar espacio para variables estáticas y variables globales; un área de solo lectura para asignar espacio para constantes y código de programa y algunas otras particiones;
Mire un ejemplo clásico muy popular en Internet:
main.cpp
int a = 0 área de inicialización global
char *p1; área global no inicializada
main()
{
int b; pila
char s[] = " abc "; Stack
char *p2; Stack
char *p3 = "123456"; 123456\0 está ubicado en el área constante y p3 está ubicado en la pila.
static int c = 0; área de inicialización global (estática)
p1 = (char *)malloc(10); )malloc(20); Heap
}
0. El método de solicitud es diferente del método de reciclaje
No sé si entienden. Un poco, la primera diferencia entre montón y pila son los diferentes métodos de aplicación: pila (el nombre en inglés es pila) es un espacio asignado automáticamente por el sistema. Por ejemplo, si definimos un carácter a, el sistema abrirá automáticamente el espacio. para ello en la pila. La pila (el nombre en inglés es montón) es el espacio que los programadores solicitan según sus necesidades, como malloc (10); Debido a que el espacio en la pila se asigna y recicla automáticamente, el ciclo de vida de los datos en la pila solo está dentro de la función del proceso en ejecución. Se libera después de la ejecución y no se puede acceder a ellos nuevamente. Siempre se puede acceder a los datos en el montón siempre que el programador no libere el espacio. Sin embargo, la desventaja es que una vez que se olvida liberar la memoria, se producirá una pérdida de memoria. Hay algunas otras diferencias. Creo que los amigos en Internet lo han resumido bien. Lo reproduzco aquí:
1. El espacio de la pila es mayor que el espacio de la aplicación, el sistema proporcionará memoria para el programa; de lo contrario, se informará una excepción y se informará un desbordamiento de la pila.
Montón: En primer lugar, debe saber que el sistema operativo tiene una lista vinculada que registra las direcciones de memoria libre. Cuando el sistema recibe una solicitud del programa, recorrerá la lista vinculada y buscará. primer montón con un espacio mayor que el espacio solicitado.
Nodo, luego elimine el nodo del nodo libre de la lista vinculada y asigne el espacio del nodo al programa. Además, para la mayoría de los sistemas, la primera dirección de este bloque de espacio de memoria será. Registre el tamaño de esta asignación para que el código de la declaración de eliminación pueda liberar adecuadamente este espacio de memoria. Además, dado que el tamaño del nodo del montón encontrado puede no ser exactamente igual al tamaño solicitado, el sistema automáticamente vuelve a colocar el exceso en la lista libre.
Esto significa que el montón debe realizar algún trabajo de seguimiento una vez finalizada la aplicación, lo que provoca problemas de eficiencia de la aplicación.
2. Comparación de la eficiencia de la aplicación
Basado en el punto 0 y el punto 1.
Pila: asignada automáticamente por el sistema, más rápida. Pero el programador no tiene control sobre ello.
Montón: es memoria recién asignada. Generalmente es más lento y propenso a la fragmentación de la memoria, pero es el más conveniente de usar.
3. Pila límite de tamaño de la aplicación: en Windows, la pila es una estructura de datos que se extiende hasta la dirección inferior y es un área continua de memoria. Lo que esta oración significa es que la dirección de la capa superior de la pila y la capacidad máxima de la pila están predeterminadas por el sistema. En WINDOWS, el tamaño de la pila es 2 M (algunos dicen 1 M, en resumen, es una constante). determinado en el momento de la compilación). Si la aplicación Si el espacio excede el espacio restante de la pila, se generará un desbordamiento. Por lo tanto, hay menos espacio disponible en la pila.
Montón: El montón es una estructura de datos que se extiende a direcciones superiores y es un área de memoria discontinua. Esto se debe a que el sistema utiliza una lista vinculada para almacenar direcciones de memoria libre, y las direcciones de memoria libre son naturalmente discontinuas. La dirección transversal de la lista vinculada es de dirección baja a dirección alta. El tamaño del montón está limitado por la memoria virtual disponible en el sistema informático. Por tanto, el montón ganará más flexibilidad y mayor espacio.
4. Contenido almacenado en el montón y la pila
Dado que el tamaño de la pila es limitado, el uso de subfunciones todavía tiene un significado físico, no solo lógico.
Pila: Cuando se llama a una función, lo primero que ingresa a la pila es la dirección de la siguiente instrucción después de la llamada a la función en la función principal (la siguiente instrucción ejecutable de la instrucción de llamada a la función), y luego, cada parámetro de la función, en la mayoría de los compiladores de C, los argumentos van en la pila de derecha a izquierda, seguidos de las variables locales dentro de la función. Tenga en cuenta que las variables estáticas no están en la pila.
Cuando finaliza la llamada a la función, las variables locales primero salen de la pila, luego los parámetros y finalmente el puntero superior de la pila apunta a la dirección donde se almacenó originalmente, que es la siguiente instrucción de la función principal, y el programa continúa desde este punto ejecutándose.
Montón: normalmente, se utiliza un byte en el encabezado del montón para almacenar el tamaño del montón. El contenido específico del montón lo organiza el programador.
También puedes consultar esta pregunta sobre el contenido almacenado.
Esta pregunta también se refiere al ciclo de vida de las variables locales.
Y bbbbbbbbbbbbb se determina en el momento de la compilación y se coloca en el montón.
Sin embargo, en accesos posteriores, una matriz en la pila es más rápida que una cadena apuntada por un puntero (como el montón).
Por ejemplo:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p = "1234567890";
a = c [1]; p >a = p[1];
return;
}
Código ensamblador correspondiente
10: a = c[1 ];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11:a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+ 1 ] <
00401073 88 45 FC mov byte ptr [ebp-4],al
Analogía de la diferencia entre montón y pila
Citando la analogía de un senior Puedes ver la diferencia entre un montón y una pila:
Usar un montón es como ir a un restaurante. Solo necesitas ordenar (hacer una solicitud), pagar la cuenta, comer (usar), y luego salir sin molestarse en cortarlo, pagar y utilizar. Luego nos fuimos, sin tener que preocuparnos más por los trabajos de preparación como picar y lavar verduras, ni por los trabajos de limpieza como lavar platos y ollas. La ventaja es que es rápido pero tiene poca libertad.
Usar "dui" es como cocinar tus platos favoritos, aunque es más problemático, se adapta más a tu propio gusto y tiene mayor libertad. Esta metáfora es muy vívida y fácil de entender. Me pregunto si te conmueve un poco.