스택 오버플로를 일으키는 가장 짧은 코드는 무엇입니까? [닫은]


160

스택 오버플로의 공개 출시를 기념하기 위해 스택 오버플로를 유발하는 가장 짧은 코드는 무엇입니까? 모든 언어를 환영합니다.

ETA :이 질문에 대해 명확하게하기 위해 가끔씩 Scheme 사용자 인 경우 : tail-call "recursion"은 실제로 반복이며, 적절한 컴파일러에 의해 비교적 간단한 반복 솔루션으로 변환 할 수있는 솔루션은 그렇지 않습니다. 계산됩니다. :-피

ETA2 : 저는 이제 "최고의 답변"을 선택했습니다. 이론적 근거 는 이 게시물 을 참조하십시오 . 기여한 모든 분들께 감사드립니다! :-)

답변:


212

이 모든 대답과 Befunge는 없습니까? 나는 그들 모두의 가장 짧은 해결책 인 공정한 금액을 베팅했다.

1

농담 아니야. 직접 해보십시오 : http://www.quirkster.com/iano/js/befunge.html

편집 : 나는 이것을 설명해야한다고 생각합니다. 1 피연산자는 1을 Befunge의 내부 스택으로 푸시하고 다른 요소가 없으면 언어 규칙에 따라 루프에 넣습니다.

제공된 인터프리터를 사용하면 결국 Befunge 스택을 나타내는 Javascript 배열이 브라우저가 다시 할당하기에 너무 커지는 지점에 도달하게됩니다. 아래의 대부분의 언어에서와 같이 더 작고 제한된 스택을 가진 간단한 Befunge 인터프리터가있는 경우이 프로그램은 더 눈에 띄는 오버플로를 더 빨리 발생시킵니다.


8
흠 ...하지만 이것이 실제로 스택 오버플로입니까 아니면 무한 루프입니까? 내 JS 인터프리터가 오버플로 되지 않았고 방금 휴가 중이었습니다.
Konrad Rudolph

3
1 명령어는 1을 스택으로 푸시하기 때문에 무한 루프가 아닙니다. 결국 Befunge 통역사는 스택 공간이 부족하지만 시간이 오래 걸립니다. :)
Patrick

18
.. 브라우저가 다운되어 CPU 팬을 오버 드라이브에 보냈습니다.
Sam152

2
놀랄 만한! 내 컴퓨터 또는 브라우저 (Opera)가 충돌하지 않았지만 두 프로세서 모두 100 %로 실행 중이고 팬 속도는 3입니다.
Secko

28
여기에 더 빠른 오버플로가 발생하는 Befunge 프로그램이 있습니다. " 1 번이 2 번이 아니라 2 번씩 32 번씩 79 번을로드합니다.
KirarinSnow


174

C # .net에서 시도해 볼 수도 있습니다.

throw new StackOverflowException();

29
내 pedant는 스택이 오버플로되지 않고 예외를 throw한다고 말합니다. 상어의 공격을받는 가장 빠른 방법은 바다에 서서 "상어의 공격!"을 외치는 것입니다. 그럼에도 불구하고, 나는 그것을 투표 할 것이다. :)
Bernard

글쎄-차이가 있습니까? 당신은 그것을 붙잡고 계속할 수 있습니까? 아니면 C #의 스택 오버플로와 정확히 똑같습니까? 그것은 하나에서 구별 할 수 있기 때문에이 경우, 그것은 어떻게 든 유래는 그러나 ...입니다 - 위의 모든 이유 upvote에

18
아무도 잡을 곳이없는 숲에 스택이 넘치면 예외가 발생합니까?

나는 '가장 짧은'이라고 말하지 않을 것입니다. 왜냐하면 당신은 그런 한 줄짜리를 컴파일 할 수있는 것이 아니기 때문입니다. 그것은 않는 것 같아요 불구하고 빠르게 스택 오버 플로우가 발생.
Dominic K


119

내 현재 최고 (x86 어셈블리)는 다음과 같습니다.

push eax
jmp short $-1

3 바이트의 객체 코드 ( 50 EB FD)가 생성됩니다. 16 비트 코드의 경우 다음도 가능합니다.

call $

또한 3 바이트 ( E8 FD FF)가됩니다.


6
"컴파일"(또는 어셈블) 후 바이트 수는 코드 골프가 아닙니다.
루이 브랜디

37
"[...] 스택 오버플로를 일으키는 가장 짧은 코드는 무엇입니까?" 소스 코드, 해석 된 코드, 기계 코드, 객체 코드 또는 관리 코드를 지정하지 않습니다.
Anders Sandvig

기록을 위해 Shin의 골프 서버를 사용하면 모든 ELF 헤더도 계산하지만 판단 할 객체 코드를 보낼 수 있습니다. 흠 ....
크리스 제스터 영

이에 대한 예는 golf.shinh.org/p.rb?FizzBuzz#x86 을 참조하십시오 . (나는 솔직히 사람들이 어떻게 99 바이트 ELF 바이너리를 만들 수 있는지 모른다.) :-P
Chris Jester-Young

7
@lbrandy : 객체 코드를 직접 작성할 수있는 사람들이 충분합니다. x86에서는 할 수 없지만 특정 마이크로 프로세서에서는 할 수 있습니다. 그런 코드를 세어 보았습니다.
Joey

113

PIC18

TK에 의해 주어진 PIC18 응답 다음 지시 사항 결과 (진) :

overflow
   PUSH
   0000 0000 0000 0101
   CALL overflow
   1110 1100 0000 0000
   0000 0000 0000 0000

그러나 CALL만으로 스택 오버플로를 수행합니다.

CALL $
1110 1100 0000 0000
0000 0000 0000 0000

더 작고 빠른 PIC18

그러나 RCALL (상대 호출)은 여전히 ​​작습니다 (전역 메모리가 아니므로 추가 2 바이트가 필요하지 않음).

RCALL $
1101 1000 0000 0000

따라서 PIC18에서 가장 작은 것은 단일 명령, 16 비트 (2 바이트)입니다. 루프 당 2 개의 명령 사이클이 필요합니다. 명령 사이클 당 4 클럭 사이클에서 8 클럭 사이클이 있습니다. PIC18에는 31 레벨 스택이 있으므로 32 루프 이후 256 클록 사이클에서 스택에 오버플로가 발생합니다. 64MHz에서는 스택을 4 마이크로 초와 2 바이트로 오버플로합니다 .

PIC16F5x (더 작고 빠름)

그러나 PIC16F5x 시리즈는 12 비트 명령어를 사용합니다.

CALL $
1001 0000 0000

다시 한 번, 루프 당 2 개의 명령 사이클, 명령 당 4 개의 클록, 따라서 루프 당 8 개의 클록 사이클.

그러나 PIC16F5x에는 2 개의 레벨 스택이 있으므로 세 번째 루프에서는 24 개의 명령으로 오버플로됩니다. 20MHz에서는 1.2 마이크로 초와 1.5 바이트로 오버플로됩니다 .

인텔 4004

인텔 4004는 8 비트 호출 서브 루틴 명령이 있습니다 :

CALL $
0101 0000

ascii 'P'에 해당하는 궁금합니다. 총 32.4 마이크로 초와 1 바이트 동안 24 클럭 사이클을 소요하는 3 레벨 스택 . (4004를 오버 클로킹하지 않는 한, 당신이 원하는 것을 알고 있습니다.)

어느 것이 befunge 답변만큼 작지만 현재 통역사에서 실행되는 befunge 코드보다 훨씬 빠릅니다.


77

씨#:

public int Foo { get { return Foo; } }


55

모든 작업에는 올바른 도구가 필요합니다. 스택 오버플로를 생성하도록 최적화 된 SO 오버플 로 언어를 충족하십시오 .

so

7
최소한의 코드로 오버플로를 생성하기 위해 특수 언어를 작성하는 경우 분명히 (1) 빈 입력으로 스택 오버플로 코드 (아마도 어셈블리 코드 항목에서 생성 된 기본 코드를 실행하는 작은 바이너리) 또는 (2 ) 모든 입력 프로그램은이 바이너리를 생성합니다.
Jared Updike 2018 년

흠, 튜링 완료되지 않았습니다. 당신은 아직 그것을 언어를 부를 수 있을지 모르겠어 ...
아담 데이비스에게

42

TeX :

\def~{~.}~

결과 :

! TeX 용량을 초과했습니다. 죄송합니다. [입력 스택 크기 = 5000].
~-> ~
    .
~-> ~
    .
~-> ~
    .
~-> ~
    .
~-> ~
    .
~-> ~
    .
...
<*> \ def ~ {~.} ~

유액:

\end\end

결과 :

! TeX 용량을 초과했습니다. 죄송합니다. [입력 스택 크기 = 5000].
\ 끝 # 1-> \ csname 끝 # 1
                      \ endcsname \ @checkend {# 1} \ expandafter \ endgroup \ if @ e ...
<*> \ end \ end

~활성화되어 있기 때문에 대신 사용할 수 있습니다 \a. 우연히 LaTeX 코드를 완전히 발견했습니다. :)
Josh Lee

35

Z-80 어셈블러-메모리 위치 0x0000에서 :

rst 00

1 바이트-0xC7-현재 PC를 스택으로 푸시하고 주소 0x0000으로 점프하는 무한 루프.


2
빈 eprom은 모두 7x (= 0x0038 호출) 명령 인 모든 0xff 일 것입니다. 오실로스코프로 하드웨어를 디버깅하는 데 유용합니다. 스택이 반복적으로 오버 플로우되어 0x0038에서 0xff의 읽기로 산재되어 주소 버스는 64K 공간을 순환합니다.
Bill Forster

29

영어로:

recursion = n. See recursion.

32
현명한 인간의 뇌는 이것에 대한 해석을 테일 콜 (tail-call)으로 최적화하며 폭발하지 않습니다. :-P
Chris Jester-Young

73
크리스, 합리적인 인간 두뇌는 요즘 희귀 해지고 있습니다.
Jason Z

20
희귀 성 ... 존재한다는 의미입니까?
Adam Lerman

11
Google 재귀
CodeFusionMobile


26

기본에서 다음은 어떻습니까?

10 GOSUB 10

(나는 두려워하는 기본 통역사가 없으므로 추측입니다.)


3
BASIC은 스택리스 언어이므로 실제로 스택 오버플로는 아닙니다. VB (스택이 있음)조차도 스택 프레임을 만들지 않고 점프하기 때문에 오버플로되지 않습니다.
Daniel Spiewak

21
즉 A의 GOSUB하는 없습니다 GOTO. 그것이 RETURN어디에서 왔는지에 따라 반드시 스택을 사용하고 있습니까?
Tom

3
예, 동의합니다. 80 년대에 BASIC에서 많은 스택 오버플로 가있었습니다 .
08 년

6
나는 이것을 재미있게하기 위해 yabasic에서 이것을 실행했고, 내 컴퓨터를 거의 무너 뜨 렸습니다. malloc은 결국 실패했지만 고맙지 만 내일처럼 페이징을하지 않았습니다.
Adam Rosenfield

2
죄송합니다. Adam .. 누군가 실수로 재귀 적으로 포크하는 프로그램을 작성했을 때의 시간을 상기시켜줍니다. 전체 실리콘 그래픽 서버를 중단했습니다.
stusmith

26

나는 Cody의 답변 힙을 좋아했기 때문에 C ++에서 비슷한 기여를합니다.

template <int i>
class Overflow {
    typedef typename Overflow<i + 1>::type type;
};

typedef Overflow<0>::type Kaboom;

코드 골프 엔트리는 아니지만 메타 스택 오버플로에 대한 모든 것! :-피


21

다음은 18 자로 된 C 기여입니다.

void o(){o();o();}

이것은 테일 콜 최적화에 훨씬 어렵다! :-피


4
나를 위해 컴파일하지 않습니다 : "`정의되지 않은 참조": P
Andrew Johnson

1
이해가 안됩니다 : 왜 o () 2x를 호출합니까?
Dinah 2016 년

3
@Dinah : 컨테스트의 제약 중 하나는 테일 콜 최적화가 재귀로 계산되지 않는다는 것입니다. 그것은 단지 반복적 인 루프입니다. o ()를 한 번만 작성했다면, 유능한 컴파일러에 의해 "o : jmp o"와 같이 테일 콜 (tail-call)으로 최적화 될 수 있습니다. o를 2 번 호출하면 컴파일러는 "o : call o; jmp o"와 같은 것을 사용해야합니다. 스택 오버플로를 만드는 것은 재귀적인 "호출"명령입니다.
Chris Jester-Young

당신은 맞습니다-나는 그 부분에주의를 기울이지 않았습니다. 명확하게 해 주셔서 감사합니다.
Dinah 2016 년


17

자바 스크립트

더 많은 캐릭터를 다듬고 더 많은 소프트웨어 상점에서 쫓겨나 게하려면 다음을 수행하십시오.

eval(i='eval(i)');

15

그루비 :

main()

그루비 스택.

Caught: java.lang.StackOverflowError
    at stack.main(stack.groovy)
    at stack.run(stack.groovy:1)
 ...

꽤 흥미 롭기 때문에 투표했습니다. 그러나 Groovy 컴파일러에서 다소 성가신 약점을 드러냅니다 (이러한 꼬리 호출은 컴파일 타임에 인라인 될 수 있음).
Daniel Spiewak

테일 콜인지 확실합니까? 프로그램 끝에서 떨어지는 것이 인터프리터 쉘을 호출하지 않습니까?
Aaron


14
Person JeffAtwood;
Person JoelSpolsky;
JeffAtwood.TalkTo(JoelSpolsky);

꼬리 재귀가 없기를 바라고 있습니다!


1
헤헤, 재밌네 대화와 관련하여 "에코 챔버 효과"라는 개념도 매우 흥미 롭습니다. 스택 오버플로를 유발하는 것은 아니지만 여전히 그렇습니다.
Chris Jester-Young

8
이것이 널 포인터 예외가 아닌가? 미안하지만 농담 인거 알아
jamesh

12

C- 가장 짧지는 않지만 재귀가 없습니다. 또한 이식성이 없습니다 : Solaris에서는 충돌하지만 일부 alloca () 구현은 여기에 오류를 반환하거나 malloc ()을 호출 할 수 있습니다. printf ()를 호출해야합니다.

#include <stdio.h>
#include <alloca.h>
#include <sys/resource.h>
int main(int argc, char *argv[]) {
    struct rlimit rl = {0};
    getrlimit(RLIMIT_STACK, &rl);
    (void) alloca(rl.rlim_cur);
    printf("Goodbye, world\n");
    return 0;
}

스택을 정말로 작게 설정하기 위해 "ulimit -s16"을 수행 할 수도 있습니다. 약 16보다 작고 프로그램이 실행되지도 않습니다 (충분하지 않은 인수).
앤드류 존슨

11

12 자로 펄 :

$_=sub{&$_};&$_

10 문자로 bash하십시오 (함수의 공간이 중요합니다).

i(){ i;};i

11

버거 하나에 버거를 4 개 이상 넣으십시오. 스택 오버플로.


1
여기 뉴질랜드에는 버거 위스콘신 (Burger Wisconsin)이 있습니다. 원한다면 4 개 이상을 쌓을 수 있다고 확신합니다. 그래도 매우 비싼 햄버거가 될 것입니다!
Chris Jester-Young



11

파이썬 :

so=lambda:so();so()

또는

def so():so()
so()

그리고 파이썬이 tail 호출을 최적화하면 ... :

o=lambda:map(o,o());o()

운 좋게도 파이썬은 테일 콜 최적화를하지 않습니다. 그렇지 않으면 지금까지 다른 두 가지 답변처럼 실격 처리됩니다. :-P
Chris Jester-Young

10

이 게시물 다음에 '우수 답변'을 선택하고 있습니다. 그러나 먼저, 나는 매우 독창적 인 공헌을 인정하고 싶습니다.

  1. 아쿠의 것. 각각은 스택 오버플로를 일으키는 새롭고 독창적 인 방법을 탐구합니다. f (x) ⇒ f (f (x))를 수행한다는 아이디어는 다음 항목에서 살펴볼 것입니다. :-)
  2. Cody는 Nemerle 컴파일러 에 스택 오버플로 를주었습니다 .
  3. 그리고 GateKiller는 스택 오버플로 예외를 던지는 것에 관한 것입니다. :-피

위의 내용을 좋아하는 것처럼 코드 골프를하는 것에 대한 도전과 응답자에게 공평한 태도를 취하기 위해 가장 짧은 코드 인 "베 펀지 (Befunge)"항목에 "최고의 답변"을 수여해야합니다. Konrad가 확실히 시도했지만 아무도 그것을 이길 수 있다고 생각하지 않으므로 Patrick을 축하합니다!

재귀에 의한 많은 스택 오버플로 솔루션을 보았을 때 아무도 (현재 글을 쓰고있는) 아무도 Y 결합기를 가져 오지 않았다는 사실에 놀랐습니다 (Dick Gabriel의 에세이, Y의 이유 , 프라이머에 대한 내용 참조 ). Y 조합자를 사용하는 재귀 솔루션과 aku의 f (f (x)) 접근 방식이 있습니다. :-)

((Y (lambda (f) (lambda (x) (f (f x))))) #f)

8

Scheme의 또 다른 흥미로운 것이 있습니다.

((람다 (x) (xx)) (람다 (x) (xx)))

아주 좋고, 좋은 대칭도 있습니다. 또한, (lambda (x) (xx)) 공식을 사용하려면 : ((Y (lambda (x) (xx))) #f)도 재미 있습니다!
Chris Jester-Young

오 예쁘다. Scheme 에서처럼 좋지는 않지만 Ruby에서도 작동합니다. lambda {| x | x.call x} .call lambda {| x | x.call x}
Wayne Conrad

7

자바

Java 솔루션의 약간 더 짧은 버전.

class X{public static void main(String[]a){main(a);}}

5
또는 (동일한 문자 수) : public static void main (String ... a) {main ();}
Michael Myers

또는 TDD들 (문자 같은 수의)에 대한 : 공용 클래스 ${@org.junit.Test 공공 무효 $ () {$ ();}}
mhaller

그래도 최단은 아니지만 (내 답변 참조)
Draemon


5

3 바이트 :

label:
  pusha
  jmp label

최신 정보

에 따르면 (?)을 (?) 이전 인텔 문서 , 이것은 또한 3 바이트입니다 :

label:
  call label


32 비트 모드에서 3 바이트입니다. 내 대답보다 훨씬 빨리 스택을 채울 것이라는 점을 고려하면 좋은 대답입니다!
Chris Jester-Young

penguin.cz/~literakl/intel/j.html#JMP 에 따르면 jmp는 8, 16 또는 32 비트 상대 대상 주소를 가진 3 바이트입니다. pusha는 4 개의 1 바이트 수이다
앤더스 샌드 빅

짧은, 근거리 및 원거리의 세 가지 유형의 jmp가 있습니다. 짧은 jmp (0xEB opcode 사용)는 2 바이트입니다. 대상은 다음 명령어에서 -128에서 127 바이트 사이 여야합니다. :-)
Chris Jester-Young

아마도 당신 말이 맞을 수도 있습니다. 나는 ... 내 어셈블러를 파고 확인 너무 게으른 해요)
앤더스 샌드 빅
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.