Límite de la pila


10

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?


55
here i mean by limit the maximum number of levels that can the stack have¿Cuál es un nivel?
tkausl


3
¿Cómo lo estás probando? ¿Está utilizando un 2-byte (dword) como entrada?
pro3carp3

66
¿Qué lenguaje de programación estás usando? Tal límite abrupto en un número fijo indica que es una limitación deliberada por el tiempo de ejecución específico de su idioma y no por el tamaño de la pila asignada por el sistema operativo. Por ejemplo, python parece imponer un límite de 1000 de forma predeterminada para evitar que golpee un desbordamiento de pila real (recuperarse de un desbordamiento de pila real es difícil)
CodesInChaos

Respuestas:


20

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):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void recfun(int x, int d) {
  printf("start recfun x=%d d=%d\n", x, d);
  fflush(NULL);
  if (d>0)
    recfun(x+1, d-1);
  printf("end recfun x=%d d=%d\n", x, d);
}

int main(int argc, char**argv) {
  int md = argc>1?atoi(argv[1]):10000;
  printf ("start md=%d\n", md);
  recfun(0, md);
  printf("end md=%d clock=%ld µs\n", md, clock());
}    
// eof recur.c

y pude ejecutar ese recurprograma (compilado con GCC 6 como gcc -Wall -O recur.c -o recur) como recur 161000 (muy por encima de su límite de 2 16 ). Con recur 256000eso también funcionó. Con recur 456000él se estrelló (con un desbordamiento de pila para el nivel x=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 a gcc , obtengo el siguiente recur.suarchivo (los números están en bytes, de acuerdo con mi intuición de límite de pila de 8Mb; no olvide el mainmarco 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 ):

 recur.c:5:10:recfun    32  static
 recur.c:13:9:main  16  static

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.


3

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.