Recientemente probé el límite de una pila en tres dispositivos con diferentes sistemas operativos (por límite, me refiero a la cantidad máxima de niveles que puede tener la pila), y noté que cada vez que alcanzo niveles de 2 ^ 16 me da error de desbordamiento, y cuando pongo 2 ^ 16-1 funciona correctamente.
Entonces mi pregunta es: ¿es eso cierto? ¿La pila tiene el límite máximo 2 ^ 16-1 por definición o depende del sistema operativo?
here i mean by limit the maximum number of levels that can the stack have
¿Cuál es un nivel?Respuestas:
Es fuertemente específico del sistema operativo (y específico de la computadora) y en algunos sistemas operativos tiene algunas formas de configurar (e incluso aumentar) el límite. Incluso es específico del compilador (o específico de su implementación de lenguaje de programación), ya que algunos compiladores (incluido el GCC reciente para algún tipo limitado de código C) pueden optimizar algunas llamadas de cola .
(algunas especificaciones de lenguaje de programación requieren optimizaciones de cola, p. ej. R5RS )
No estoy seguro de que su pregunta tenga sentido (y ciertamente no es su límite de 2 16 ). En mi escritorio Linux (Debian / Sid / x86-64, kernel Linux 4.9, 32Gb RAM, Intel i5-4690S), podría tener una pila de llamadas de hasta 8 megabytes (y podría aumentar ese límite, si realmente quisiera )
Multi-threading y ASLR están haciendo que su pregunta sea mucho más compleja . Ver, por ejemplo, pthread_attr_setstack (3) . Lea también sobre las pilas divididas (a menudo utilizadas por las implementaciones de Go ) y sobre el estilo de paso de continuación . Ver también esta respuesta.
Para lo que vale, acabo de probar el siguiente código C99 (y también C11):
y pude ejecutar ese
recur
programa (compilado con GCC 6 comogcc -Wall -O recur.c -o recur
) comorecur 161000
(muy por encima de su límite de 2 16 ). Conrecur 256000
eso también funcionó. Conrecur 456000
él se estrelló (con un desbordamiento de pila para el nivelx=272057
). No tengo paciencia para otras pruebas. Intenta eso en tu computadora. No olvides pedir optimizaciones.Una regla general (para computadoras de escritorio, computadoras portátiles, tabletas) podría ser mantener su pila de llamadas por debajo de un megabyte.
Al pasar también
-fstack-usage
agcc
, obtengo el siguienterecur.su
archivo (los números están en bytes, de acuerdo con mi intuición de límite de pila de 8Mb; no olvide elmain
marco de la llamada y, lo que es más importante, el diseño de la pila inicial, instalado por el kernel al hacer execve (2 ) ..., para crt0 ):PD. Mi Arduino tiene un Atmega328 con solo 2Kbytes de RAM, por lo que ciertamente no puede repetirse tanto. Supongo que solo unos pocos cientos de marcos de pila son prácticamente posibles en Arduinos.
fuente
El enlazador establece el tamaño de la pila para el hilo principal de un proceso de Windows. El valor predeterminado es 1 MB, pero se puede ajustar con el interruptor / STACK. Los hilos creados más tarde pueden usar el parámetro dwStackSize de la función CreateThread.
Entonces ... si está probando varios sistemas operativos Windows, todos han tenido el mismo tamaño de pila predeterminado desde al menos NT4.0.
fuente