2010-03-23 6 views
10

왜 다음 프로그램이 segfault입니까? 이 (GCC 4.4.3 및 그 소리 1.5 (트렁크)) 세그먼테이션 폴트 (segfault) 왜재귀 메인() - 왜 세그 폴트입니까?

int main() { main(); } 

은 종료하고 정의에 따라서 유효하지 않는 재귀 비록, 내가 볼 수 없습니다.

+24

스택 오버플로라고합니다. –

+0

@wic : 그리고 한 말처럼, 그것은 식물이 아니며, 진짜 질문이었습니다. 큰 재미! –

+0

@ T.J : 예, OP는 천재이며, 심지어 모른다 : –

답변

26

자체를 호출 할 때마다 스택 공간을 조금 할당하기 때문에; 결국 스택 공간과 segfaults가 부족합니다. 나는 그것이 segfault와 함께가는 것이 놀랍다. 나는 예상 했었을 것이다 (드럼 롤) stack overflow!

+0

이 기계는 4GB의 RAM을 가지고 있으며 segfaults 1 초도 채 걸리지 않습니다. 나는 RAM이 부족하다고 생각하지 않는다. 스택이 너무 작아서 그렇게 빨리 일어날 수 있다는 것을 의미합니까? – user299831

+10

@ user2999831 스택은 일반적으로 1 메가 바이트와 같은 것으로 제한됩니다. – sharptooth

+0

@ user299831 : 시스템에있는 RAM의 용량과 아무 관련이 없습니다. 각 스레드마다 최대 스택 크기가 있습니다 (Visual Studio에서는 1MB를 변경할 수 있음). 이 크기를 초과하면 스택 오버플로가 발생합니다. – Naveen

35

당신은 얻을 stack overflow (!)

+2

처음 링크를 클릭하면 즉시 오버플로가 발생합니다. 매우 깊은 스택이 아닙니다. 아마도 ... – AnT

2

그것은 당신의 시스템에서 세그먼트 폴트로 진단 스택 오버 플로우에 이르게.

3

은 스택 오버 플로우를 발생하는 스택 오버플

10
int main() { main(); } 

원인베이스 케이스없이 같이 Recurse이다.

그러나,

이 같은 최적화 된 버전 (안 디버그 모드) :

int main() { 
    return main(); 
} 

무한 루프 일명 꼬리 재귀 호출 재귀를 변환합니다!

+0

실제로이 예제에서 gcc -O3은 루프를 멀리도 최적화합니다. –

+0

@ 닉 두 사람이 어떻게 다른가요? – Adil

+0

@Adil 컴파일러에 따라 다르지만 컴파일러가 주를 명시 적으로 "반환"하지 않으면 컴파일러가 꼬리 재귀로 변환하지 못할 수도 있습니다. (예 :'if (1) {main();} return 0;과 if (1) {return main();} return 0;') –

1

각 함수 호출은 스택에 항목을 추가하며이 항목은 함수가 종료 될 때 스택에서 제거됩니다. 여기에는 종료 조건이없는 재귀 함수 호출이 있습니다. 그래서 무한한 숫자의 함수가 차례로 호출됩니다.이 함수는 절대로 나갈 수 없으며 스택에서 결코 제거되지 않고 스택 오버 플로우로 이어질 것입니다.