스택 오버플로를 생성하는 가장 좋은 방법 [닫기]


146

프로그래머는 명백한 재귀로 인한 스택 오버플로의 오류를 확실히 알고 있습니다. 그러나 좋아하는 언어가 그 오류를 뱉어내는 데 이상하고 특이한 방법이 많이 있습니다.

목표 :

  1. 오류 출력에서 ​​명확하게 볼 수있는 스택 오버플로가 발생해야합니다.
  2. 명백한 재귀를 사용할 수 없습니다.

유효하지 않은 프로그램의 예 :

// Invalid, direct obvious recursion.
methodA(){ methodA(); }
// Invalid, indirect, but obvious recursion.
methodA(){ methodB(); }
methodB(){ methodA(); }

가장 는 가장 독창적 인 방법 입니다. 즉, 다음과 같은 명백한 대답을 피하십시오.

throw new StackOverflowError(); // Valid, but very boring and downvote-deserving.

지금 답변을 수락했지만 더 많은 답변을 추가해도 괜찮습니다. :)


14
선택한 검색 엔진에서 '스택 오버플로'를 쿼리하는 것으로 알려져 있지만 stackoverflow.com으로 이동하여 생성하는 경향이 있습니다.
— OJFord

21
Internet Explorer를 사용하십시오. 하나를 잡는 확실한 방법 :)
— asgoth February

64
스택 오버플로를 생성하는 가장 이상한 방법은 codegolf.stackexchange.com에 사람들이 스택 오버플로를 생성하는 가장 이상한 방법을 게시하도록 요청하는 인기 경연 대회를 게시하는 것입니다. 응답자는 질문에 대한 솔루션을 테스트 할 때 스택 오버플로를 발생시킵니다. 그래도 테스트하지 않았으므로 작동하는지 확신 할 수 없습니다 (그래서 답변으로 게시하지 않은 이유).
— Tim Seguine

3
이 방법의 일부입니다 : joelonsoftware.com/items/2008/09/15.html
— robert

11
도요타는 드라이브 (내 차이, 이봐, 잠깐 입니다 ... 도요타)
— 점잔 빼는 ossifrage

답변:


224

파이썬

import sys
sys.setrecursionlimit(1)

이렇게하면 통역사가 즉시 실패하게됩니다.

$ cat test.py
import sys
sys.setrecursionlimit(1)
$ python test.py
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e947b18> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e8f6050> ignored
$ 

재귀를 사용하는 대신 스택을 축소하여 즉시 오버플로합니다.


12
귀엽지 만 원래의 질문이 내 의견으로는 무엇을 목표로하고 있는지는 아닙니다.
— Nit

12
@Nit 문제가 보이지 않습니다. 이 솔루션이 불만족스러운 것은 무엇입니까?
— SimonT

17
@ masterX244 예, 질문의 요점은 "일반적인 방법으로하지 마십시오"입니다.
— Plutor

24
@Plutor 일반적으로 StackOverFlow를 의도적으로 설정합니까?
— Kiwy

15
이것이 처음 게시 될 때 이것은 약간 영리 했어요 .
— primo

189

파이썬

import webbrowser
webbrowser.open("http://stackoverflow.com/")

7
환상적인. 멋지고 우아합니다.
— James Webster

103
문자 그대로. 매우 대답합니다.
— Tim Seguine

47
글쎄, 이것은 스택 오버플로를 보여 주지만 이것을 생성 하기 위해 Jeff Atwood 또는 Joel Spolsky가 실행하는 경우에만 작동합니다.
— 기계 달팽이

10
@TimSeguine 와우.
— Sean Allred

9
오류 출력에 없으므로 답변이 아닙니다.
— Pierre Arlaud

131

C / 리눅스 32 비트

void g(void *p){
        void *a[1];
        a[2]=p-5;
}
void f(){
        void *a[1];
        g(a[2]);
}
main(){
        f();
        return 0;
}

반환 주소를 덮어 쓰면 작동하므로 호출하기 전의 g시점으로 돌아갑니다 . 반송 주소가 스택에 있지만 조정이 필요할 수있는 모든 플랫폼에서 작동합니다.mainf

물론, 배열 외부에 쓰는 것은 정의되지 않은 동작 이며, 콧수염을 파란색으로 칠하는 것보다 스택 오버플로를 일으킬 것이라는 보장은 없습니다. 플랫폼, 컴파일러 및 컴파일 플래그의 세부 사항은 큰 차이를 만들 수 있습니다.


1
이것이 segfault를 생성하지 않습니까?
— 11684

4
이상한 스택 조작과 + 재귀에 +1!
— RSFalcon7

6
@ 11684, 그것은 정의되지 않은 동작이므로 일반적으로 충돌 할 수 있습니다. 32 비트 Linux (내가 테스트 한)에서는 배열 외부에 쓰고 반환 주소를 덮어 쓰며 스택이 오버플로 될 때까지 충돌하지 않습니다.
— ugoren

46
"당신의 콧수염을 파란색으로 칠하십시오"-> 그 줄은 저를 가졌습니다.
— Aneesh Dogra

2
와. 이것은 환상적으로 난독 화됩니다.
— MirroredFate

108

자바 스크립트 / DOM

with (document.body) {
    addEventListener('DOMSubtreeModified', function() {
        appendChild(firstChild);
    }, false);

    title = 'Kill me!';
}

브라우저를 죽이려면 콘솔에서 시도하십시오.


53
나는 당신이 더 많은 +1 투표를받을 자격이 있다고 확신하지만, 슬프게도 사람들은 투표하기 전에 이것을 시도했습니다 .... lol
— Reactgular

5
글쎄, 그것은 효과적이었다. 작업 관리자를 열어서 죽일 수도 없었습니다.
— primo

1
Chrome을 사용하고 탭을 닫습니다. 문제 해결됨.
— Cole Johnson

1
with (document.body) { addEventListener('DOMSubtreeModified', function() { appendChild(firstChild); }, false); title = 'Kill me!'; } 15:43:43.642 TypeError: can't convert undefined to object
— Brian Minton

1
젠장 내 Firefox가 중단되었습니다
— Farhad

91

자바

여기 어딘가에 이와 같은 것을 보았습니다.

편집 : 내가 본 곳을 찾았습니다 : StackOverflow Error 를 발생시키는 가장 짧은 프로그램에 대한 Joe K의 답변

public class A {
    String val;
    public String toString() {
        return val + this;
    }

    public static void main(String[] args) {
        System.out.println(new A());
    }
}

일부 Java 초보자는 혼동 될 수 있습니다. 재귀 호출을 숨 깁니다. String 이기 때문에 val + this됩니다 .val + this.toString()val

여기에서 실행되는 것을 참조하십시오 : http://ideone.com/Z0sXiD


30
실제로, new StringBuilder().append(val).append("").append(this).toString()그리고 마지막 추가는 String.valueOf (...)를 호출하고 String.valueOf (...)를 호출합니다. 이렇게하면 스택 추적이 약간 달라집니다 (세 가지 방법).
— Paŭlo Ebermann

2
@ PaŭloEbermann 그래, 맞아. 그러나 그것이된다고 말하는 것이 훨씬 쉽습니다 "" + this.toString().
— 저스틴

2
+ "" +언뜻보기에는 쓸모없는 것처럼 보이기 때문에 사람들에게 팁을 줄 수 있다고 생각합니다 . String val;그리고 return val + this;약간 비웃을지도 모른다
— Cruncher

@Cruncher는 전혀 아닙니다. Java 코더 인 경우, ""-String 구성 중에 int를 문자열에 연결하는 쉬운 방법은+ ""
— Justin

5
실제 응용 프로그램에서는 무한 재귀 및 스택 오버플로 오류를 피하는 것이
— 좋습니다

77

씨

꽤 쉬운:

int main()
{
    int large[10000000] = {0};
    return 0;
}

10
명백하지 않은 경우 +1! 그것은 매우 시스템 의존적 임에도 불구하고 ( ulimit -s unlimited쉘에서 리눅스에서 이것을 해결합니다)
— RSFalcon7

4
@ RSFalcon7, +1 주셔서 감사하지만 나에게 이것은 실제로 가장 분명했습니다!
— Shahbaz

14
@Cruncher : 재귀를 일으키지 않습니다. 주어진 문제는 스택을 날려 버리는 것이었다. 많은 운영 체제에서 스택은 크기가 고정되어 있으며 천만 정수보다 훨씬 작으므로 스택이 손상됩니다.
— Eric Lippert

2
@ HananBinder, 내가 테스트 한 Linux에서는 스택 오버플로 오류가 발생하지 않습니다. 스택 오버플로로 인해 소유하지 않은 세그먼트에 액세스 할 수 있으므로 세그먼트 오류가 발생합니다. 무한 재귀 함수 호출도 세그멘테이션 오류를 발생시키기 때문에 Linux에 스택 오버플로 오류가 있는지 확실하지 않습니다.
— Shahbaz 2013

3
~0uC에서 꽤 큰 숫자입니다.
— Vortico

63

C의 비 재귀 스택 오버플로

전화 컨벤션이 일치하지 않습니다.

typedef void __stdcall (* ptr) (int);

void __cdecl hello (int x) { }

void main () {
  ptr goodbye = (ptr)&hello;
  while (1) 
    goodbye(0);
}

로 컴파일하십시오 gcc -O0.

__cdecl함수는 호출자가 스택을 정리 __stdcall하고 수신자가이를 처리 할 것으로 예상하므로 typecast 함수 포인터를 통해 호출하면 정리가 수행되지 않습니다 main. 매개 변수를 각 호출에 대해 스택으로 푸시하지만 아무 것도 표시하지 않습니다. 스택 채우기.


2
스택을 스팸으로 보내는 좋은 방법 : P
— masterX244

62

자바 스크립트

window.toString = String.toLocaleString;
+this;

5
이것은 저평가되었습니다.
— Ry-

1
무엇을 +this합니까?
— NobleUplift

8
단항 +는 ToNumber 추상 연산을 호출합니다. 힌트 유형의 숫자와 함께 ToPrimitive 연산을 사용합니다. 개체의 ToPrimitive는 [[DefaultValue]] 내부 메서드를 사용합니다.이 메서드는 숫자 힌트를 전달할 때 먼저 valueOf () 메서드가 있는지 확인하고 프리미티브를 반환합니다. window.valueOf ()는 객체를 반환하므로 [[DefaultValue]]는 toString ()을 호출 한 결과를 반환합니다. window.toString이 수행하는 첫 번째 작업 (현재 toLocaleString)은 'this'에서 toString을 호출합니다. 반복.
— Ryan Cavanaugh

3
Chrome에서 '너무 많은 재귀'오류가 발생하면 Chrome에서 작동합니까? 스택 오버플로와 Chrome이 스택 오버플로 예외를 제공하는 방식입니다.
— David Conrad

4
당신은 사용해야합니다 +{toString:"".toLocaleString}:-)
— Bergi

62

Java 7과 java 8이 이전 답변 에서 내 사악한 코드에 면역된다는 사실에 좌절했습니다 . 그래서 그 패치가 필요하다고 결정했습니다.

성공! 나는 printStackTrace()던졌다 StackOverflowError. printStackTrace()디버깅 및 로깅에 일반적으로 사용되며 위험 할 수 있다고 합리적으로 의심하는 사람은 없습니다. 이 코드가 악용되어 심각한 보안 문제가 발생할 수 있음을 확인하는 것은 어렵지 않습니다.

public class StillMoreEvilThanMyPreviousOne {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        throw new EvilException();
    }

    public static class EvilException extends Exception {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}

어떤 사람들은 이것이 명백한 재귀라고 생각할 수도 있습니다. 그렇지 않습니다. EvilException생성자는 호출하지 않는 getCause()그 예외가 실제로 결국 안전하게 던져 질 수 있도록 방법을. getCause()메소드를 호출 해도 결과가 발생하지 않습니다 StackOverflowError. 재귀는 JDK의 일반적으로 의심되지 않는 printStackTrace()동작과 예외를 검사하는 데 사용되는 디버깅 및 로깅을위한 타사 라이브러리 내에 있습니다. 또한 예외가 발생하는 장소는 예외가 처리 된 장소와 매우 거리가 먼 것 같습니다.

어쨌든, 여기에 a를 던지고 StackOverflowError재귀 적 인 메소드 호출이 포함되지 않은 코드가 있습니다. 은 StackOverflowError외부 일 mainJDK의에서, 방법 UncaughtExceptionHandler:

public class StillMoreEvilThanMyPreviousOneVersion2 {
    public static void main(String[] args) {
        evilMethod();
    }

    private static void evilMethod() {
        throw new EvilException();
    }

    public static class EvilException extends RuntimeException {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}
Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "main"

2
: D 및 이제 크로스 Java 버전 스택 오버 플로우 호환 방법. 사악한 놈! : D
— Kiwy

9
이 경우 재귀를 분명히 고려하는 경향이 있습니다.
— Taemyr

1
@BlacklightShining getCause()메서드를 호출 해도 결과가 나타나지 않습니다 StackOverflowError. getCause()메소드를 재귀 적으로 호출하는 JDK 코드가 있다는 사실에 의존합니다 .
— Victor Stafusa

2
본문 getCause을 그냥 변경하면 return this;Java를 너무 영리하게 바꿀 수 있습니다. " CIRCULAR REFERENCE" 임을 알 수 있습니다.
— David Conrad

1
StackOverflowErrorjdk-1.7.0.21p2v0의 OpenBSD 5.5 패키지에 버그가 있기 때문에 나는 얻지 못했습니다 . 던지지 않습니다 StackOverflowError. 그것은 SIGSEGV핵심을 때리고 덤프합니다.
— kernigh

57

리눅스 x86 NASM 어셈블리

section .data
    helloStr:     db 'Hello world!',10 ; Define our string
    helloStrLen:  equ $-helloStr       ; Define the length of our string

section .text
    global _start

    doExit:
        mov eax,1 ; Exit is syscall 1
        mov ebx,0 ; Exit status for success
        int 80h   ; Execute syscall

    printHello:
        mov eax,4           ; Write syscall is No. 4
        mov ebx,1           ; File descriptor 1, stdout
        mov ecx,helloStr    ; Our hello string
        mov edx,helloStrLen ; The length of our hello string
        int 80h             ; execute the syscall

    _start:
        call printHello ; Print "Hello World!" once
        call doExit     ; Exit afterwards

스포일러:

printHello에서 돌아 오는 것을 잊었으므로 다시 _start로 건너 뜁니다.


78
조립시에는 분명한 것이 없습니다.
— 11684

21
@ 11684 : 그 반대가 사실이라고 생각합니다. 어셈블리에서는 아무도 코드를 실제로 사용하여 추상화를 사용할 수 없기 때문에 모든 것이 분명합니다.
— 메이슨 휠러

3
단순함과 우아함이 훌륭합니다.
— haneefmubarak

11
@MasonWheeler : 나는 모든 것이 명백한 것이 아니라 눈에 보이는 것이라고 말하는 것을 선호합니다 ... 보이는 것과 명백한 것의 차이점을 보는 좋은 방법은 underhanded.xcott.com
— Olivier Dulac

2
잊어 버리는 실수를 자주 기억합니다ret
— Ruslan

48

컴파일 타임에 C ++

template <unsigned N>
struct S : S<N-1> {};

template <>
struct S<0> {};

template
struct S<-1>;
$ g ++ -c test.cc -ftemplate-depth = 40000
g ++ : 내부 컴파일러 오류 : 분할 오류 (프로그램 cc1plus)
전체 버그 보고서를 제출하십시오.
적절한 경우 전처리 된 소스를 사용합니다.
지침을 참조하십시오.

이 소스 파일은 재귀가 없으며, 클래스 중 하나도 기본 클래스로 존재하지 않으며 간접적으로도 마찬가지입니다. (C ++ 이와 같이 템플릿 클래스, S<1>및 S<2>완전히 별개의 클래스이다.) 세그멘테이션 폴트 컴파일러 재귀 후 스택 오버 플로우에 기인한다.


7
나는 이것이 당신의 메타 프로그램에서 명백한 재귀라고 불렀을 것이라고 고백합니다.

2
GCC는 재귀를 감지하고이 쪽을 우아하게 멈 춥니 다 (4.8 이상은 괜찮은 것 같습니다)
— Alec Teal

2
template <typename T> auto foo(T t) -> decltype(foo(t)); decltype(foo(0)) x;조금 더 짧습니다.
— Casey

2
@hvd GCC의 버그를 이용하는 것 같습니다. clang은 잘못된 사용법을 포착 하지만 이미 알고 있다고 가정하지만 GCC는 거의 2 메가 바이트의 오류 메시지를 뿜어냅니다.
— Casey


45

배쉬 (위험 경고)

while true
do 
  mkdir x
  cd x
done

엄밀히 말하면 오버플로를 직접 스택하지는 않지만 " 지속적인 스택 오버 플로우 생성 상황 " 합니다. 디스크가 가득 찰 때까지이를 실행하고 "rm -rf x ", 그 중 하나가 맞았습니다.

그러나 모든 시스템에서 발생하는 것은 아닙니다. 일부는 다른 것보다 강력합니다.

큰 위험 경고 :

어떤 시스템은 이것을 아주 잘 처리합니다 잘못 하므로 정리하기가 매우 어려울 수 있습니다 ( "rm -rf"자체가 recusion 문제가 발생하기 때문에). 정리를 위해 비슷한 스크립트를 작성해야 할 수도 있습니다.

확실하지 않으면 스크래치 VM에서이 방법을 사용하는 것이 좋습니다.

추신 : 물론 배치 스크립트로 프로그래밍하거나 수행하는 경우에도 마찬가지입니다.
PPS : 특정 시스템의 작동 방식에 대한 의견을 얻기 위해 방해가 될 수 있습니다.


내가 쓴 것처럼 : 많은 시스템에서 rm -rf는 다운하려고 시도하고 하나에 도달합니다 (더 이상 요즘은 64 비트 주소 공간이 없지만 더 작은 스택의 작은 컴퓨터에서는 더 낫습니다). 물론, "rm"구현이있을 수도 있는데, 다른 방식으로 ...
— blabla999

2
나에게 while cd x; do :; done; cd ..; while rmdir x; cd ..; done;이것을 돌봐야 할 것 같습니다.
— Blacklight Shining

당신은 절대적으로 옳습니다 (즉, "정리를위한 비슷한 스크립트"라는 의미입니다). 그러나 디스크 (또는 할당량)가 가득 차면 일부 시스템은 그 상황을 잘못 처리하는 데 사용되므로 나중에 로그인하기가 어려울 수도 있습니다. 루트로 들어가서 스크립트를 작성해야합니다 (오늘날 PC에서는 쉽지만 여러 사용자가 컴퓨터를 사용하는 고대에는 종종 힘들었습니다).
— blabla999

재미 있고, 이것은 아래의 스몰 토크 마법보다 더 많은 표를 얻을 수 (그 생각하지 않았다!)
— blabla999

누군가 Windows에서 이것을 시도 했습니까?
— Sarge Borsch

43

자바

Java Puzzlers 의 멋진 것입니다 . 무엇을 인쇄합니까?

public class Reluctant {
    private Reluctant internalInstance = new Reluctant();

    public Reluctant() throws Exception {
        throw new Exception("I'm not coming out");
    }

    public static void main(String[] args) {
        try {
            Reluctant b = new Reluctant();
            System.out.println("Surprise!");
        } catch (Exception ex) {
            System.out.println("I told you so");
        }
    }
}

실제로 StackOverflowError와 함께 실패합니다.

생성자의 예외는 빨간 청어입니다. 이것은 책이 그것에 대해 말한 것입니다.

생성자를 호출하면 인스턴스 변수 이니셜 라이저가 생성자의 본문보다 먼저 실행 됩니다. 이 경우 변수의 이니셜 라이저 internalInstance가 생성자를 재귀 적으로 호출합니다. 그 생성자는 차례로 internalInstanceReluctant 생성자 등을 다시 호출하여 자체 필드를 초기화합니다 . 이러한 재귀 호출로 인해 StackOverflowError생성자 본문이 실행될 기회를 얻습니다. StackOverflowError가 Error아닌 의 하위 유형 이므로 Exceptioncatch 절이 catch main하지 않습니다.


41

유액

\end\end

여기에\end 설명 된대로 반복적으로 무한 루프로 확장 되므로 입력 스택이 오버플 로 됩니다 .

TeX는 TeX capacity exceeded, sorry [input stack size=5000]이와 유사하거나 실패합니다 .


1
TeX / LaTeX 문제를 기다리고있었습니다. 그 것들이 가장 끔찍합니다. 일반적으로, 제가하는 일이 갑자기 재귀 적 인 것을 쓸 때 프로그래밍으로 간주한다는 것을 잊었습니다.
— Ernir


1
"TeX 용량을 초과했습니다. 죄송합니다." TeX는 실패했을 때 매우 정중합니다.
— Alex A.

40

BF

결국 스택을 오버플로 할 것입니다. 인터프리터가 스택을 만드는 시간에 달려 있습니다 ...

+[>+]

5
그 코드는 나에게 인생의 게임을 생각 나게한다.
— 아담 아 롤드

10
엄밀히 말하면, brainfuck에는 스택이 없습니다.
— 페예 쇼코

6
당신이 원한다면 @fejesjoco 테이프.
— Timtech

32

컴파일 타임에 C #

Microsoft C # 컴파일러가 스택을 날려 버리는 방법에는 여러 가지가 있습니다. C # 컴파일러의 "표현식이 너무 복잡하여 컴파일 할 수 없습니다"라는 오류가 표시 될 때마다 스택이 손상 되었기 때문에 거의 확실합니다.

파서는 재귀 적하이므로 충분히 깊게 중첩 된 언어 구조가 스택을 날려 버립니다.

 class C { class C { class C { ....

표현식 파서는 일반적으로 재귀되는 측에서 재귀를 제거하는 것에 대해 매우 영리합니다. 보통:

x = 1 + 1 + 1 + 1 + .... + 1;

엄청나게 깊은 구문 분석 트리를 빌드하면 스택을 날려 버리지 않습니다. 그러나 다른 쪽에서 재귀를 강제로 수행하면 :

x = 1 + (1 + (1 + (1 + ....+ (1 + 1))))))))))))))))))))))))))))))))))))))))))...;

그런 다음 스택을 날릴 수 있습니다.

이것들은 프로그램이 매우 크다는 우아한 특성을 가지고 있습니다. 또한 시맨틱 분석기가 작은 시스템으로 무한한 재귀로 들어가는 것이 가능합니다. 유형 시스템에서 특정 홀수주기를 제거하기에 충분히 영리하지 않기 때문입니다. (Roslyn이이를 개선 할 수 있습니다.)

public interface IN<in U> {}
public interface IC<X> : IN<IN<IC<IC<X>>>> {}
...
IC<double> bar = whatever;
IN<IC<string>> foo = bar;  // Is this assignment legal? 

이 분석이 왜 무한 재귀로 진행되는지 설명합니다.

http://blogs.msdn.com/b/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx

더 많은 흥미로운 예를 보려면이 백서를 읽어야합니다.

http://research.microsoft.com/en-us/um/people/akenn/generics/FOOL2007.pdf


2
정확한 오류 메시지는 fatal error CS1647: An expression is too long or complex to compile near (code)입니다. 이 오류 메시지에 대한 설명서는 here 이며 "컴파일러에서 코드를 처리하는 동안 스택 오버플로가 발생했습니다."
— bwDraco

32

인터넷에서 (일일 수십억 명의 사람들이 사용)

Redirects, HTTP status code: 301

예를 들어, Dell 지원 웹 사이트에서 (공격 없음, Dell 죄송)

URL에서 지원 TAG를 제거하면 무한 리디렉션됩니다 . 다음 URL에서 ######은 지원되는 TAG입니다.

http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/######?s=BSD&~ck=mn

스택 오버플로와 동일하다고 생각합니다.


5
좋은 방법은 : 파이어 폭스는 그렇게 요청이 유래의 rquivalent : 어떤 해결 될 수없는 리디렉션 있음을 알려줍니다
— masterX244

3
리디렉션은 무한 하지 않습니다. "다시 시도" /Errors/를 누르면 URL에 몇 개 더 추가 한 다음 HTTP 400 잘못된 요청을받은 후 중지됩니다. 그러나 이것은 무한 리다이렉션보다 더 나은 스택 오버플로를 만듭니다.
— nandhp

@ nandhp, 동의하지만, 최신 브라우저, IE 등이 아닌 제 3 세계 브라우저를 생각한다면 그들은이 상황에 대한 단서가 없습니다.
— codeSetter

2
Wget의 응답 방식은 다음과 같습니다. pastebin.com/pPRktM1m
— bwDraco

1
http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/...
— Vortico

31

PHP

루핑 요소로만 수행되는 스택 오버 플로우입니다.

$a = array(&$a);
while (1) {
    foreach ($a as &$tmp) {
        $tmp = array($tmp, &$a);
    }
}

설명 (스포일러를 보려면 마우스를 가져 가십시오) :

인터프리터가 $tmp배열 을 가비지 수집하려고 할 때 ( $tmp여기에서 재 할당 할 때) 프로그램은 segfault 입니다. 배열이 너무 깊어서 (자체 참조) 가비지 수집기가 재귀로 끝납니다.


16
PHP의 GC가 자기 참조 구조를 감지 할 수 없습니까? 정말?! 아야. 즉 이다 악.
— Peter C

1
예,하지만 완벽하지는 않습니다. 왜 while (1) { $a = array(&$a); }또는 비슷한 것이 메모리 제한에 도달 했는지 몇 가지 이유가 있습니다 .
— bwoebi

네, PHP가 객체 지향 개발과 관련하여 제대로 작동하지 않는 이유와 같습니다. (추상화, 상속 등)
— pythonian29033

1
@ pythonian29033 정교한 관리가 필요하십니까?
— vvondra

30

자바

나는 분명히 스택 오버플로 오류를 발생시켜야하지만 그렇지 않은 프로그램과 정반대를했습니다.

public class Evil {
    public static void main(String[] args) {
        recurse();
    }

    private static void recurse() {
        try {
            recurse();
        } finally {
            recurse();
        }
    }
}

힌트 : 프로그램은 O (2 n ) 시간에 실행되며 n 은 스택 크기 (일반적으로 1024)입니다.

에서 자바 퍼즐 러 (Puzzler) # 45 :

우리 기계 가 초당 10 10 호출을 실행 하고 초당 10 10 예외를 생성 할 수 있다고 가정합시다 . 이는 현재 표준에 따라 상당히 관대합니다. 이러한 가정하에 프로그램은 약 1.7 × 10 291 년 후에 종료됩니다 . 이 관점에서 태양의 수명은 10 10 년으로 추정 되므로이 프로그램이 끝나는 사람은 아무도 없을 것입니다. 무한 루프는 아니지만 그럴 수도 있습니다.


3
명백한 재귀 ...별로 흥미롭지 않습니다.
— Kami

5
@Kami 사용해 보셨습니까? 실제로 StackOverflowError가 발생 했습니까? 분명해 보이지만 그렇지 않습니다.
— ntoskrnl

예외가 발생했다고해서 결코 발생하지 않았다는 의미는 아닙니다. 이 프로그램은 시간 O (n) 이후에 스택 오버플로 예외를 발생
— 시킵니다.

1
@CodesInChaos 좋아, 그래서 이것을 다시 확인했고 올바른 버전이 finally아닌을 사용 catch하고 실행 시간은 O (2 ^ n)입니다. 답변이 업데이트되었습니다.
— ntoskrnl

@ntorkrnl 좋은 것 + 1'd; btw는 이미 컴파일러를
— 스택 오버 플로우로 가져 왔습니다

30

씨#

첫 번째 게시물이므로 나에게 쉽게 가십시오.

class Program
{
    static void Main()
    {
        new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Invoke(null, null);
    }
}

이것은 단순히 스택 트레이스를 생성하고 최상위 프레임 (마지막 호출 Main())을 가져 와서 메소드를 가져 와서 호출합니다.


설명 없이는 분명하지 않은 좋은 selfinvoke 방법; +
— 1'd

"무엇이 잘못 될 수 있는가?"로 해당 코드를 주석 처리해야합니다. : P
— Spaceman

26

자바

  • Java 5에서는 printStackTrace()무한 루프를 시작합니다.
  • Java 6에서는을 printStackTrace()던집니다 StackOverflowError.
  • Java 7 및 8에서는 수정되었습니다.

미친 것은 Java 5와 6에서 사용자 코드에서 오는 것이 아니라 JDK의 코드에서 발생한다는 것입니다. printStackTrace()실행하기에 위험 할 수있는 합리적인 용의자는 없습니다 .

public class Bad {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        Exception a = new Exception();
        Exception b = new Exception(a);
        a.initCause(b);
        throw a;
    }
}

7
네; 아무것도없는 stackoverflow는 codetrolling의 가장 친한 친구이자 사냥에 심각한 두통이 있습니다
— masterX244

2
궁금한 점이 있으면 C #의 동등한 코드로 인해 무한 루프가 발생합니다. 그러나 InnerException속성은 읽기 전용이며 생성자에서 설정되므로이를 반영하려면 리플렉션이 필요합니다.
— Athari

17

자바 스크립트 : 비 재귀, 반복 함수 돌연변이

var f = function() {
    console.log(arguments.length);
};

while (true) {
    f = f.bind(null, 1);
    f();
}

여기에는 전혀 재귀가 없습니다. 단일 함수 호출에서f 스택 을 오버플로 할 수있을 때까지 점점 더 많은 인수로 반복적으로 커리됩니다 . console.log부분은 경우에 당신이 그것을하는 데 걸리는 얼마나 많은 인수보고 싶어 선택 사항입니다. 또한 영리한 JS 엔진이이를 최적화하지 않도록합니다.

CoffeeScript의 코드 골프 버전, 28 자 :

f=->
do f=f.bind f,1 while 1

14

서사시 실패와 C #

using System.Xml.Serialization;

[XmlRoot]
public class P
{
    public P X { get { return new P(); } set { } }
    static void Main()
    {
        new XmlSerializer(typeof(P)).Serialize(System.Console.Out, new P());
    }
}

그것이 실패하는 방식은 서사시이며, 내 마음이 완전히 불었습니다.

여기에 이미지 설명을 입력하십시오

그것은 겉보기에는 무한대로 넘어지는 일련의 이상한 이미지의 한 프레임에 불과합니다.

이것은 가장 이상한 일이되어야합니다. 아무도 설명 할 수 있습니까? 분명히 들여 쓰기에 사용되는 공간이 계속 늘어 나면 흰색 블록이 나타납니다. .NET 4.5가 설치된 Win7 Enterprise x64에서 발생합니다.

나는 실제로 아직 끝을 보지 못했습니다. 당신이 바꿀 경우 System.Console.Out에 System.IO.Stream.Null, 그것은 꽤 빨리 죽는다.

설명은 매우 간단합니다. 단일 속성을 가진 클래스를 만들고 항상 포함 유형의 새 인스턴스를 반환합니다. 그래서 그것은 무한히 깊은 객체 계층입니다. 이제 우리는 그것을 통해 읽을 수있는 무언가가 필요합니다. 그것이 내가 사용하는 곳 XmlSerializer입니다. 분명히 재귀를 사용합니다.


네; 직렬화 ftw : P; 그러나 더 재미있는 것은 ythe quirk가 snakeyaml이 속성을 얻는 방법과 같이 클래스가 완전히 재귀하는 방식과 같이 코드 외부에있을 때입니다.
— masterX244

1
글쎄, 오버플로는 내 코드 외부에서 발생하지만 내가 게시 한 실제 이유는 콘솔의 예기치 않은 부작용 때문입니다 :-)
— fejesjoco

.Net 4 (cmd를 통해 실행될 때조차도)를 사용하면 공백 만 있고 흰색 블록은 없기 때문에 흰색 비트는 .Net 4.5와 관련이 있거나 환경 설정 방법과 관련이 있어야한다고 생각합니다. 내 생각에 Win7 Enterprise 버전의 cmd 또는 .Net 4.5 콘솔 에뮬레이터는 특정 문자 조합을 '콘솔 색상 배경 ​​변경'으로 처리합니다.
— Pharap

Aero가 켜진 Win7 x64 Professional에서 .NET 4.5로 재현 할 수 없음
— Ray

또한 재현 할 수 없습니다. .NET 4.5, Windows 8.1 Pro.
— bwDraco

13

세게 때리다

_(){ _;};_

많은 사람들이 재귀가 명백 하다는 것을 인식 할 수는 있지만 꽤 좋아 보입니다. 아니?

실행하면 다음을 볼 수 있습니다.

Segmentation fault (core dumped)

5
이것은 더 예쁘고 나쁘다 :_(){_|_;};_
— RSFalcon7

1
@ RSFalcon7 포크 폭탄 경고! (또한 {구문 적으로 정확하기 위해 공백이 필요하지 않습니까?)
— Shining

3
뿐만 아니라이 시도:(){:|:;}:
— 타렉 Eldeeb에게

14
소름 끼치는 돌연변이 이모티콘처럼 보입니다.
— Tim Seguine

8
배쉬 이모티콘 : 얼굴 먹는 사람, 스택 킬러.
— NobleUplift

12

하스켈

(슬프지만 사실까지 적어도 ghc-7.6와 비록 O1멀리 문제를 최적화 할 수 있습니다 이상)

main = print $ sum [1 .. 100000000]

테일 콜 최적화를 자동으로 수행하면 안됩니까?
— blabla999

2
@ blabla999 : 테일 콜은 Haskell과 관련이 없으며, 이러한 문제를 일으키는 은밀한 게으름으로 인해 주로 썽크가 발생합니다. 이 경우 꼬리 호출을 사용하는의 sum관점에서 구현 foldl되지만 문제는 누산기를 평가하지 않기 때문에 원래 목록만큼 큰 덩어리가 생성됩니다. 로 전환하면 문제가 사라지고 foldl' (+)엄격하게 평가되므로 테일 호출에서 WHN을 반환합니다. 또는 내가 말했듯이 GHC의 최적화를 켜면!
— 반 시계 회전을 중단

aah-흥미 롭다. 만약 아무도 썽크를 기다리지 않는다면 (즉, 인쇄물을 남기지 않는다면) 가비지 수집기는 그것들을 앞뒤로 모을 것이다.
— blabla999

1
BTW,이 중 어느 것도 Haskell 표준에 의해 실제로 지정되지 않았습니다. 평가가 엄격 하지 않아도됩니다. 즉 , 결과가 완전히 필요하지 않은 경우 비 종료 계산은 영원히 차단 되지 않습니다. 실제로 차단하는 시간은 구현에 달려 있으며 표준 게으른 GHC에서는 결과를 요청할 때까지 전혀 차단되지 않습니다.
— 반 시계 회전을 중단

2
하스켈은 멋지다.
— blabla999

12

잡담

이렇게하면 새 메서드가 즉석에서
  만들어져 새 메서드가 즉석에서
    만들어져 새 메서드가 즉석에서 만들어 져서
      ...
    ...
  ..
로 전송됩니다.

더 작은 향신료는 스택 메모리와 힙 메모리를 동시에 강조하면서 더 길고 더 긴 메소드 이름과 수신자로 엄청난 수를 만들어서 구멍을 내릴 때 수신기로 엄청난 숫자를 가져옵니다 ... ).

정수로 컴파일 :

downTheRabbitHole
    |name deeperName nextLevel|

    nextLevel := self * 2.
    name := thisContext selector.
    deeperName := (name , '_') asSymbol.
    Class withoutUpdatingChangesDo:[
        nextLevel class 
            compile:deeperName , (thisContext method source copyFrom:name size+1).
    ].
    Transcript show:self; showCR:' - and down the rabbit hole...'.
    "/ self halt. "/ enable for debugging
    nextLevel perform:deeperName.

잠시 후 "2 downTheRabbitHole"...
... 을 평가하여 점프 하면 디버거가 끝나고 RecursionException이 표시됩니다.

그런 다음 모든 엉망을 정리해야합니다 (SmallInteger와 LargeInteger는 이제 많은 원더 랜드 코드를 갖습니다).

{SmallInteger . LargeInteger } do:[:eachInfectedClass |
    (eachInfectedClass methodDictionary keys 
        select:[:nm| nm startsWith:'downTheRabbitHole_'])
            do:[:each| eachInfectedClass removeSelector:each]

또는 브라우저에서 앨리스의 원더 랜드를 제거하면서 시간을 보내십시오.

다음은 추적 헤드의 일부입니다.

2 - and down the rabbit hole...
4 - and down the rabbit hole...
8 - and down the rabbit hole...
16 - and down the rabbit hole...
[...]
576460752303423488 - and down the rabbit hole...
1152921504606846976 - and down the rabbit hole...
2305843009213693952 - and down the rabbit hole...
[...]
1267650600228229401496703205376 - and down the rabbit hole...
2535301200456458802993406410752 - and down the rabbit hole...
5070602400912917605986812821504 - and down the rabbit hole...
[...]
162259276829213363391578010288128 - and down the rabbit hole...
324518553658426726783156020576256 - and down the rabbit hole...
[...]
and so on...

추신 : 스몰 토크의 지속적인 변경 로그 파일을 나중에 정리할 필요가 없도록 "withoutUpdatingChangesFile :"이 추가되었습니다.

PPS : 도전에 대한 감사 : 새롭고 혁신적인 무언가에 대해 생각하는 것이 재미있었습니다!

PPPS : 일부 스몰 토크 방언 / 버전은 넘쳐나는 스택 프레임을 힙에 복사하므로 메모리 부족 상황이 발생할 수 있습니다.


2
순수한 형태의 흑 마법에 대한 LOL +1
— masterX244

시간이 있으면 익명 클래스의 익명 메소드를 사용하여 가장 어두운 토끼 구멍을 만들어 "개선"할 수 있습니다.
— blabla999

12

씨#

정말 크고 struct재귀가 없으며 순수한 C #이며 안전하지 않은 코드는 아닙니다.

public struct Wyern
{
    double a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Godzilla
{
    Wyern a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Cyclops
{
    Godzilla a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Titan
{
    Cyclops a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Titan();
        // 26×26×26×26×8 = 3655808 bytes            
        Console.WriteLine("Size={0}", Marshal.SizeOf(A));
    }
}

키커로서 디버그 창에 충돌을 일으켜 {Cannot evaluate expression because the current thread is in a stack overflow state.}


그리고 일반 버전 (NPSF3000 제안에 감사드립니다)

public struct Wyern<T>
    where T: struct
{
    T a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;        
}


class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Wyern<Wyern<Wyern<Wyern<int>>>>();
    }
}

더 일반적인 코드
— 메타 크림이

재귀처럼 보이지만 중첩 된 형식 인수로 가능합니다.
— ja72

1
내가 게시하기 전에 C # 구조체 응답을 보지 못했습니다. 나는 여전히 조금 다른 접근법을 가지고 있기 때문에 우리는 그것들을 공존시킬 수 있습니다.
— Thomas Weller

11

씨#

재정의 ==연산자 의 잘못된 구현 :

public class MyClass
{
    public int A { get; set; }

    public static bool operator ==(MyClass obj1, MyClass obj2)
    {
        if (obj1 == null)
        {
            return obj2 == null;
        }
        else
        {
            return obj1.Equals(obj2);
        }
    }

    public static bool operator !=(MyClass obj1, MyClass obj2)
    {
        return !(obj1 == obj2);
    }

    public override bool Equals(object obj)
    {
        MyClass other = obj as MyClass;
        if (other == null)
        {
            return false;
        }
        else
        {
            return A == other.A;
        }
    }
}

운영자 operator==를 사용하여 자신 을 호출 하는 것이 분명 ==하지만 일반적으로에 대해 ==그렇게 생각하지 않으므로 해당 함정에 빠지기 쉽습니다.


11

SnakeYAML을 사용하여 응답 시작

class A
{

    public static void main(String[] a)
    {
         new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point());
    }
}

편집 : ungolfed it

그것이 어떻게 작동하는지 알아내는 것은 독자에게 달려 있습니다. : P (tip : stackoverflow.com)

그건 그렇고 : 재귀는 SnakeYAML에 의해 동적으로 이루어집니다 (직렬화 된 필드를 어떻게 감지하고 Point소스 코드 에서보고하는지 알 수 있습니다 )

편집 : 작동 방식을 알려줍니다.

SnakeYAML은 쌍을 찾는다 getXXX및 setXXX대한 동일한 이름 mthod XXX게터의 타입의 파라미터 설정 부와 동일 리턴; 그리고 놀랍게도 Point클래스에는 Point getLocation()and void setLocation(Point P)가 있습니다. SnakeYAML은이를 인식하지 못하고 해당 문제와 StackOverflow에서 반복됩니다. 내부에서 그들과 함께 일하고 HashMapstackoverflow.com에 요청할 때 하나를 발견 했습니다.


10

씨#

잘못 구현 된 속성 게터

class C
{
   public int P { get { return P; } }
}

static void Main()
{
   int p = new C().P;
}

14
이모. 이것은 명백한 재귀의 전형적인 예입니다 ... (그리고 유효하지 않습니다)
— Ole Albers

2
글쎄, 당신이 한 번 한 번만하고 C # getter가 생각했던 방식으로 작동하지 않는다는 것을 알면 분명합니다. 결국이 코드는 멤버 변수 선언이므로 실제 멤버 변수를 작성하면 안되는 이유는 무엇입니까?
— meustrus

2
이것은 복잡한 작업 방식에 지나지 않습니다static void Main() { Main(); }
— Jodrell

5
@Jodrell Main()실수로 재귀를 쓰지 않을 것 입니다. 그러나 실수로 재귀 속성을 작성한 다음 스택 오버플로로 혼동되는 것은 매우 간단합니다.
— svick

1
이것은 누군가 C #을 집어들 때 유용합니다.
— 2rs2ts
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.