모든 함수가 종료되지 않고 자체적으로 호출하는 기능이 있다고 가정 해 보겠습니다.재귀 세그먼트 화 오류 및 StackGuard
myFunction(){
myFunction()
}
이 기능이 포함 된 프로그램을 실행하면 결국 세그먼트 오류가 발생합니다. 왜 이런 일이 생길까요? 스택 공간이 부족합니까?
StackGuard는이 오류로부터 보호 할 수 있습니까? 그 이유는 무엇?
모든 함수가 종료되지 않고 자체적으로 호출하는 기능이 있다고 가정 해 보겠습니다.재귀 세그먼트 화 오류 및 StackGuard
myFunction(){
myFunction()
}
이 기능이 포함 된 프로그램을 실행하면 결국 세그먼트 오류가 발생합니다. 왜 이런 일이 생길까요? 스택 공간이 부족합니까?
StackGuard는이 오류로부터 보호 할 수 있습니까? 그 이유는 무엇?
재귀가 무한하기 때문에 각 호출에 대해 반환 주소와 기본 포인터 (프레임 포인터)가 적어도 스택에 푸시되므로 결국 스택 공간이 부족하거나 더 일반적으로 메모리가 부족합니다. 메모리는 한정된 자원이기 때문에.
이 무한 재귀를 "설계"한 프로그래머이기 때문에이 문제를 방지 할 수있는 방법은 없습니다. "이 결함으로부터 보호"를 기대 하시겠습니까? 그것이 프로그램의 디자인이기 때문에 나는 잘못이 아니라고 말했다. OS가 프로그램을 중단하게 만드는 유한 리소스가 부족합니다.
jmp_buf home;
void myFunction(void)
{
myFunction();
}
void SegvHandler(int signal)
{
longjmp(home);
}
int main(void)
{
signal(SIGSEGV, SegvHandler);
if (setjmp(home)) {
printf("Oops...\n)
return 1;
}
myFunction();
return 0;
}
함수를 호출 할 때마다 해당 함수 호출을 위해 메모리에 새 스택 프레임이 만들어집니다. 이 스택은 함수가 반환 될 때 사라집니다. 함수가 반환하지 않고 새로운 호출을 계속 호출하면 스택 프레임을 계속 작성하므로 스택 프레임을 유지하기 위해 메모리가 부족합니다.
해당 코드를 실행하려고하면 구문 오류로 인해 빌드되지 않습니다. –
이 재귀에는 중지 조건이 없습니다. 너는 무엇을 기대 하느냐? –
스택은 제한된 리소스입니다. Windows에서 프로세스의 기본 스택 크기는 단일 MB입니다. 그리고 그것을 막을 수있는 유일한 방법은 재귀를 실제로 종료시키는 종료 조건을 갖는 것입니다. –