2009-07-10 4 views
33

스택 오버플로 오류 란 무엇입니까? 어떤 종류의 프로그램/프로그래밍 언어가 발생할 것입니까? 웹 응용 프로그램 코드에서 발생할 가능성이 있습니까? wikipedia에서, 나오긴의스택 오버플로 란 무엇입니까?

+0

http://en.wikipedia.org/wiki/Stack_overflow –

답변

26

: 너무 많은 메모리가 호출 스택에 사용되는 경우 소프트웨어에서

는 스택 오버플로가 을 발생합니다. 많은 프로그래밍 언어에서 호출 스택에는 제한된 메모리 양이 포함되어 있습니다. 일반적으로 은 프로그램의 시작 부분에서 결정됩니다.

스택은 프로그램의 서브 루틴이 실행을 끝낼 때 제어를 리턴해야하는 지점을 기록하는 데이터 구조입니다. 리턴 어드레스는 서브 루틴이 호출 될 때 스택에 푸시 된 입니다. 서브 루틴 실행이 완료되면 리턴 어드레스는 이 스택에서이됩니다. 많은 서브 루틴이 있고 스택에 공간이 없으면 스택 오버플로가 발생합니다.

또한 로컬 변수를 저장하기위한 것이므로 로컬 변수가 너무 큰 경우 스택에 저장할 공간이 없기 때문에 스택 오버플로가 발생하는 경우가 있습니다.

DrawLine 서브 루틴이 DrawSquare이라는 다른 서브 루틴에서 호출 될 때 위키 백과에는 스택 그림이 포함되어 있습니다.이 그림이 스택 구조를 더 잘 이해하는 데 도움이되기를 바랍니다. 깊은 함수 재귀지나치게 큰 스택 변수 :

stack diagram

는 스택 오버 플로우의 두 가지 주요 원인이 있습니다. 이들은 거의 모든 프로그래밍 언어에서 일반적인 용어이므로 스택 오버 플로우는 언어의 복잡성 외에도 발생할 수 있습니다.

Guffa 기여 : 스택에는 가비지 수집과 관련이 없습니다.최신 응용 프로그램은 스택이 더 커지므로 스택 오버플로가 발생할 확률이 약간 적지 만 차이점은 없습니다.

+1

내가 이해하는 바에 따르면, 이것은 또한 가비지 수집을 사용하는 현대 언어에서 (적어도별로는 아니지만, 나는별로 확실하지 않다) 발생하지 않는다. – thebrokencube

+1

물론 스크립트 언어로 발생할 수 있습니다. 그들은 콜 스택 (call stack)을 가지며, 이것은 자연스럽게 넘칠 수 있습니다. – Guffa

+1

예를 들어 자바에서 매우 심한 재귀를 사용할 때 일어날 수 있습니다. http://stackoverflow.com/questions/860550/stack-overflows-from-deep-recursion-in-java –

5

: 너무 많은 메모리가 호출 스택에 사용되는 경우 소프트웨어에서

는 스택 오버플로가 발생합니다. 많은 프로그래밍 언어에서 호출 스택에는 제한된 메모리가 포함되어 있습니다. 일반적으로 프로그램 시작시 결정됩니다. 호출 스택의 크기는 프로그래밍 언어, 시스템 아키텍처, 멀티 스레딩 및 사용 가능한 메모리의 양을 포함하여 여러 요소에 따라 다릅니다. 호출 스택에 너무 많은 메모리가 사용되면 스택이 오버 플로우됩니다. 일반적으로 프로그램 충돌이 발생합니다. 소프트웨어 버그의 1이 클래스는 일반적으로 영어를 이해하기 조금 어렵다, 프로그램 오류 중 하나가 두 종류의

+1

+1 당신은 매달려 있습니다. – steamer25

+1

이것은 대답이 아니다. –

+1

이 대답은 좋은 생각이다. –

1

헥타르에 의해 발생하지만 난 내가 무엇을 당신의 묻는 얻을 생각된다.

스택 (duh ...)을 사용 중이고 메모리 할당/읽기 문제가있을 때 스택 오버플로가 발생합니다. "웹 프로그램"에서 (HTML, PHP, JS에 대해 이야기하고 있다고 가정), 스택을 사용하지 않거나 사용 된 언어가 이러한 문제를 방지하는 저수준 메모리 제어를 허용하지 않습니다. Wikipedia에서

+2

메모리 할당 제어가 부족하여 스택 오버플로를 방지하지 못한다. –

+2

거의 모든 언어가 호출 스택을 가지고 있기 때문에 서브 루틴이 끝난 후 코드가 원래 위치로 되돌아 갈 수 있도록 코드가 필요합니다. 이 호출 스택은 일반적으로 고정 크기이므로 반환하지 않고 너무 많은 서브 루틴을 호출하면 스택이 가득 차서 오버플로합니다. –

18

스택은 여러 스택 프레임을 포함하며 메모리에 저장됩니다. 함수가 호출 될 때마다 새 스택 프레임이 스택에 추가됩니다. 스택 프레임에는 호출되는 함수에 전달할 인수와 반환 주소가 포함되어 있으므로 호출 된 함수가 완료되면 cpu는 반환 할 위치를 알고 있으므로 호출 함수를 계속 실행할 수 있습니다. 스택 프레임은 호출되는 함수의 로컬 변수가 사용할 메모리를 포함 할 수도 있습니다. 이 예에서

메인 함수 호출 WriteCustomerDetails 그 PrintToConsole가 WriteCustomerDetails 기능 조회 데이터의 개별 비트 쓰는 부름 : 스택

'======= 위쪽 ==== ================= '
기능 : PrintToConsole
Arg : John Smith, 34 Acacia Avenue, Age 23
'----------- ------------------------------------------------ '
기능 : WriteCustomerDetails
Arg : John Smith
'------------------------------------------------ ----------- '
기능 : 기본
'====== 스택 맨 아래 ================= '

스택에 충분한 공간이 예약되지 않은 경우 스택 오버플로가 발생합니다. 일반적으로 스택은 하나의 커다란 연속적인 메모리 블록에 위치하므로 청크로 나누어지지 않습니다. 즉, 하나의 커다란 메모리가 필요하다는 것을 의미합니다. 따라서 런타임에서 스택을 위해 예약 된 공간을 늘리거나 늘릴 수 없습니다 그것이 가득 차면.

스택 오버플로는 실수로 자체를 호출하는 함수가 작성 될 때 발생할 수 있습니다. 때로는 함수에서 'if'또는 어떤 시점에서 호출을 중지하는 함수의 조건이있는 한 함수 자체를 호출하는 것이 좋습니다. 이를 재귀 함수라고합니다. 하지만 아무런 멈추지 않고 계속해서 함수를 호출하거나 둘 이상의 함수가 서로를 계속 호출하면 매우 빠르게 스택 메모리를 모두 먹게됩니다. 왼쪽이 없으면 스택 오버플로가 발생하고 프로그램이 충돌합니다.

모든 프로그램에서이 문제가 발생할 수 있으며 반드시 복잡 할 필요는없고 웹 사이트를 실행하는 코드에서 발생할 수 있습니다. 또한 스크립트 언어에서도 발생할 수 있습니다.

+1

아주 좋은 대답, +1 –

7

너무 많은 스택 공간을 사용하면 스택 오버플로가 발생합니다. 일반적으로 다음과 같은 두 가지 경우가 있습니다.

첫 번째는 코드에 오류가있어 종료하지 않고 순환 루프가 발생하는 경우입니다. 예를 들어 자체에서 읽는 속성 :

public int Length { 
    get { 
     return Length; 
    } 
} 

두 번째는 재귀 루프가 너무 깊은 경우입니다. 스택 공간이 제한되어 있으므로 알고리즘을 특정 횟수만큼 중첩 할 수만 있습니다. 알고리즘이 너무 깊어서 스택 공간이 부족해지기 전에 스택 공간이 부족하면 스택 오버플로가 발생합니다. 예 :

public bool Odd(int value) { 
    if (value == 0) { 
     return false; 
    } else { 
     return !Odd(value - 1); 
    } 
} 

이 메서드를 너무 큰 값으로 호출하면 너무 깊게 중첩되어 스택 오버플로가 발생합니다.

+3

두 예제 모두에서 스택 오버플로가 발생하는 이유는 재귀입니다. 그러나 실제로 또 다른 아주 간단한 이유가 있습니다. 스택에 할당 된 (로컬) 변수 또는 함수 인수가 너무 큰 경우 일반적으로 배열에서 발생합니다 (http://en.wikipedia.org/wiki/Stack_overflow 참조). –