2010-03-23 30 views
10

¿Por qué el siguiente programa segfault?principal recursivo(): ¿por qué segfault?

int main() { main(); } 

A pesar de que se trata de una recursividad que no termina y es, por tanto, inválida, por definición, no veo por qué segfaults (gcc 4.4.3 y 1.5 sonido metálico (tronco)).

+24

Se llama 'desbordamiento de pila' –

+0

@wic: Y hasta donde se puede decir, no es una planta, era una pregunta real. ¡Gran diversión! –

+0

@ T.J: Sí, el OP es un genio y ni siquiera lo sabe :) –

Respuesta

26

Porque cada vez que se llama a sí mismo asigna un poco de espacio de pila; finalmente se queda sin espacio de pila y segfaults. Estoy un poco sorprendido de que vaya con un segfault; ¡Hubiera esperado (batería) stack overflow!

+0

Esta máquina tiene 4 GB de RAM y segfaults en menos de un segundo No creo que se quede sin RAM. ¿Quieres decir que la pila solo puede ser tan pequeña que pasa tan rápido? – user299831

+10

@ user2999831 La pila generalmente está limitada a algo así como 1 megabyte. – sharptooth

+0

@ user299831: no tiene nada que ver con la cantidad de RAM que tiene en su sistema. Para cada subproceso, hay un tamaño de pila máximo (1 MB en Visual Studio, se puede cambiar). Si superas ese tamaño, obtienes un desbordamiento de pila. – Naveen

35

usted consigue una stack overflow (!)

+2

¡Es sorprendente que cuando hago clic en ese enlace la primera vez, inmediatamente me llegue el desbordamiento de la pila! No es una pila muy profunda, supongo ... – AnT

2

Conduce a desbordamiento de pila que se diagnostica como violación de segmento en el sistema.

3

es recurse sin un caso base, lo que provoca un desbordamiento de pila

10
int main() { main(); } 

provocará un desbordamiento de pila.

Pero,

una versión optimizada (no el modo de depuración) de esta manera:

int main() { 
    return main(); 
} 

transformará la recursividad en una llamada recursiva de cola, también conocido como un bucle infinito!

+0

En realidad para este ejemplo, gcc -O3 también optimizará el bucle. –

+0

@Nick ¿Cómo son los dos diferentes? – Adil

+0

@Adil, depende del compilador, pero es posible que si no "devolvemos" explícitamente el principal, el compilador no lo convierta en una recursividad final. (casos de ejemplo: 'if (1) {main();} return 0;' y 'if (1) {return main();} return 0;') –

1

Cada llamada de función agrega en pila y esta entrada se eliminará de la pila cuando salga la función. Aquí tenemos una llamada a función recursiva que no tiene condición de salida. Por lo tanto, es un número infinito de llamadas de función una detrás de otra y esta función nunca obtiene salida y allí no se elimina nunca de la pila y dará lugar al desbordamiento de pila.

Cuestiones relacionadas