スタックオーバーフローを引き起こす最も短いコードは何ですか?[閉まっている]


160

スタックオーバーフローの公開を記念して、スタックオーバーフローを引き起こす最も短いコードは何ですか?どんな言語でも大歓迎です。

ETA:この質問を明確にするために、私が時々Schemeユーザーであることを確認します。末尾呼び出しの「再帰」は実際には反復であり、適切なコンパイラによって比較的簡単に反復ソリューションに変換できるソリューションは、カウントされます。:-P

ETA2:「ベストアンサー」を選択しました。根拠については、この投稿を参照してください。貢献してくれた皆さん、ありがとう!:-)

回答:


212

これらの答えはすべてあり、Befungeはありませんか?私はかなりの額を賭けます、それはそれらすべての最も短い解決策です:

1

冗談じゃない。ぜひお試しください:http : //www.quirkster.com/iano/js/befunge.html

編集:私はこれを説明する必要があると思います。1オペランドはBefungeの内部スタックに1をプッシュし、他に何もないため、言語のルールに従ってループに入れられます。

提供されたインタープリターを使用すると、最終的に(つまり最終的には)、Befungeスタックを表すJavascript配列が大きくなりすぎてブラウザーが再割り当てできなくなる点到達します。以下のほとんどの言語でそうであるように、小さくて制限されたスタックを持つ単純なBefungeインタープリターがある場合、このプログラムはより顕著なオーバーフローをより速く引き起こします。


8
うーん...しかし、これは本当にスタックオーバーフローですか、それとも単なる無限ループですか?私のJSインタープリターはオーバーフローせ、いわば休暇になりました。
Konrad Rudolph

3
1命令が1をスタックにプッシュするため、これは無限ループではありません。最終的に、Befungeインタプリタはスタックスペースを使い果たしますが、しばらく時間がかかります。:)
Patrick

18
あなたは..私のブラウザをクラッシュさせ、..私のCPUファンをオーバードライブに送りました。
Sam152 2009年

2
すごい!マイコンピュータまたはブラウザ(オペラ)はクラッシュしませんでしたが、両方のプロセッサが100%で実行されていたし、ファン速度が3にあった
Secko

28
ここではより高速なオーバーフローしBefungeプログラムです: " それは、数32の79枚のコピー、それがラップアラウンドするすべての2倍ではなく、数1の2つのコピーロード
KirarinSnow


174

C#.netでもこれを試すことができます

throw new StackOverflowException();

29
私のペダントは、スタックがオーバーフローすることはなく、ただ例外をスローすると言っています。それは、サメに襲われる最も早い方法は海に立って「サメの攻撃!」と叫ぶことだと言っているようなものです。それにもかかわらず、私は賛成票を投じます。:)
バーナード

さて-違いはありますか?それをキャッチして続行できますか?それともc#のstackoverflowのようですか?その場合、スタックオーバーフローは1と区別がつかないため、どういうわけかスタックオーバーフローです...しかし、上記のすべての理由
Mo.

18
スタックが森の中でオーバーフローして誰も捕まえられない場合、例外がスローされますか?

あなたがそのようなワンライナーをコンパイルできるようではないので、私は「最短」とは言いません。それはない、私は推測してもすぐにスタックオーバーフローを投げます。
ドミニクK

159

ネメルレ

これにより、StackOverflowExceptionでコンパイラークラッシュします。

def o(){[o()]}

119

私の現在のベスト(x86アセンブリ)は次のとおりです。

push eax
jmp short $-1

これにより、3バイトのオブジェクトコード(50 EB FD)が生成されます。16ビットコードの場合、これも可能です。

call $

これも3バイト(E8 FD FF)になります。


6
「コンパイル」(またはアセンブル)後のバイトのカウントは、コードゴルフではありません。
Louis Brandy

37
「[...]スタックオーバーフローを引き起こす最も短いコードは何ですか?」ソースコード、インタープリターコード、マシンコード、オブジェクトコード、またはマネージコードを指定していません...
Anders Sandvig

記録として、Shinのゴルフサーバーでは、判断するオブジェクトコードを送信できますが、ELFヘッダーもすべてカウントされます。うーん....
クリス・ジェスター=ヤング

この例については、たとえば、golf.shinh.org / p.rb?FizzBu​​zz#x86を参照してください。(正直なところ、人々が99バイトのELFバイナリをどのように作成できるかはわかりません。):-P
Chris Jester-Young

7
@lbrandy:オブジェクトコードを直接記述できる人は十分にいます。x86ではできませんが、特定のマイクロプロセッサではできます。私はそのようなコードを数えます。
ジョーイ

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つのレベルのスタックがあるため、3番目のループでは24命令でオーバーフローします。20MHzでは、1.2マイクロ秒と1.5バイトでオーバーフローします

インテル4004

インテル4004は、 8ビットの呼び出しサブルーチン命令があります。

CALL $
0101 0000

アスキー「P」に対応する好奇心のために。合計32.4マイクロ秒、1バイトで 24クロックサイクルかかる3レベルのスタック。(あなたが4004をオーバークロックしない限り-さあ、あなたはあなたがしたいのを知っています。)

これはbefungeの回答と同じくらい小さいですが、現在のインタープリターで実行されているbefungeコードよりはるかに高速です。




55

すべてのタスクには適切なツールが必要です。スタックオーバーフローを生成するように最適化されたSOオーバーフロー言語を満たします。

so

7
最小限のコードでオーバーフローを生成するための特殊な言語を作成している場合は、明らかに(1)空の入力がスタックオーバーフローコード(おそらく、アセンブリコードエントリから生成されたネイティブコードを実行する小さなバイナリ)を生成するか、または(2 )すべての入力プログラムが上記のバイナリを生成します。
Jared Updike、

うーん、チューリング完全ではありません。あなたはまだ言語それを呼び出すことができれば、私は...知らない
アダム・デイビス

42

TeX:

\def~{~.}~

結果:

!TeXの容量を超えています。申し訳ありません[入力スタックサイズ= 5000]。
〜->〜
    。
〜->〜
    。
〜->〜
    。
〜->〜
    。
〜->〜
    。
〜->〜
    。
...
<*> \ def〜{〜。}〜

ラテックス:

\end\end

結果:

!TeXの容量を超えています。申し訳ありません[入力スタックサイズ= 5000]。
\ end#1-> \ csname end#1
                      \ endcsname \ @checkend {#1} \ expandafter \ endgroup \ if @ e ...
<*> \ end \ end

~はアクティブなので、の代わりに使用できます\a。そして、偶然にLaTeXコードを完全に発見しました。:)
ジョシュリー

35

Z-80アセンブラ-メモリ位置0x0000に:

rst 00

1バイト-0xC7-現在のPCをスタックにプッシュし、アドレス0x0000にジャンプする無限ループ。


2
空白のepromはすべて最初の7(= 0x0038を呼び出す)命令である0xffsであることを覚えています。これは、オシロスコープでハードウェアをデバッグするのに役立ちます。スタックが繰り返しオーバーフローし、0x0038からの0xffの読み取りが散在しているため、アドレスバスは64Kスペースを循環します。
ビルフォースター

29

英語で:

recursion = n. See recursion.

32
賢明な人間の脳は、この呼び出しの解釈もテールコールで最適化し、爆破しません。:-P
クリスジェスター-ヤング

73
クリス、賢明な人間の脳は最近珍しいものになりつつあります。
Jason Z

20
希少性...あなたはそれらが存在するということですか?
アダムラーマン

11
Googleの再帰
CodeFusionMobile 2009年

29

別のPHPの例:

<?
require(__FILE__);

4
括弧をスキップすることでショートすることもできます(ただし、最初の括弧の代わりにスペースが含まれます)。
アレックス

26

BASICの以下についてはどうでしょうか。

10 GOSUB 10

(私は恐れているBASICインタープリターがいないので、それは推測です)。


3
BASICはスタックレス言語であるため、実際にはスタックオーバーフローではありません。VB(スタックがある)でも、ジャンプするだけでスタックフレームを作成しないため、これでオーバーフローすることはありません。
Daniel Spiewak 2008

21
それはGOSUBではなくGOTOです。RETURNそれが呼び出された場所に向かっているので、確かにスタックを使用していますか?
トム

3
ええ、同意します。私は80年代にBASICで多くのスタックオーバーフローを経験しました。
2008

6
私はこれを面白さのためにyabasicで実行しましたが、コンピューターをほとんど停止しました。mallocが最終的に失敗したことに感謝しますが、私は明日はないようにページングしていました。
Adam Rosenfield、

2
おっと申し訳ありません、Adam ...誰かが誤って再帰的にフォークしたプログラムを書いたときのことを思い出しました:Silicon Graphicsサーバー全体をダウンさせました。
stusmith 2008年

26

私はコーディの回答ヒープが大好きだったので、C ++での私の同様の貢献を次に示します。

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

typedef Overflow<0>::type Kaboom;

決してコードゴルフエントリではありませんが、それでもメタスタックの何かがオーバーフローしています!:-P


21

これが私のCの貢献です。18文字の重さです。

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

これは、最適化を末尾呼び出しするのがはるかに困難です!:-P


4
コンパイルできません: "` main 'への未定義の参照 ":P
Andrew Johnson

1
わかりません:なぜo()を2回呼び出すのですか?
ダイナ

3
@Dinah:私のコンテストの制約の1つは、末尾呼び出しの最適化が再帰としてカウントされないことでした。それは単なる反復ループです。o()を1度だけ書いた場合、それは(有能なコンパイラーによって) "o:jmp o"のようなものにテールコール最適化できます。oを2回呼び出すと、コンパイラーは「o:call o; jmp o」のようなものを使用する必要があります。スタックをオーバーフローさせるのは、再帰的な「呼び出し」命令です。
クリスジェスター-ヤング

あなたは正しいです-私はその部分に注意を払いませんでした。説明していただきありがとうございます。
ダイナ


17

JavaScript

さらに数文字をトリミングし、より多くのソフトウェアショップから追い出されるようにするには、次のようにします。

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

15

Groovy:

main()

$ groovy stack.groovy:

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

かなり面白いので投票しました。ただし、Groovyコンパイラーのやや厄介な弱点を明らかにします(このような末尾呼び出しはコンパイル時にインライン化できます)。
Daniel Spiewak 2008

テールコールですか?プログラムの最後から落ちることはインタプリタシェルを起動しませんか?
アーロン


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

ここでは、末尾再帰がないことを期待しています!


1
へへ、おかしい。会話に関連して、「エコーチャンバー効果」の考え方も非常に興味深いものです。スタックオーバーフローを引き起こすことはあまりありませんが、それでもまだです。
Chris Jester-Young

8
これはnullポインタ例外ではないでしょうか?すみません、それは冗談です。
jamesh 2008年

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より小さく、プログラムは実行されません(argsが不十分なようです!)。
Andrew Johnson

11

12文字のperl:

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

10文字でbash(関数内のスペースは重要です):

i(){ i;};i

11

1つのハンバーガーに4つ以上のパテを入れてみてください。スタックオーバーフロー。


1
ここニュージーランドには、大きくて薄いパテを使用するバーガーウィスコンシンがあります。必要に応じて、4つ以上積み重ねることができると思います。でもそれはとても高いハンバーガーになるでしょう!
Chris Jester-Young

多分:alafista.com/2010/05/10/...はそうでないかもしれない:cheaplightning.blogspot.com/2010/06/...
BCS


11

Python

so=lambda:so();so()

または:

def so():so()
so()

そしてPythonが最適化されたテールが呼び出す場合...:

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

幸運なことに、Pythonは末尾呼び出しの最適化を行いません。それ以外の場合、これまでの2つの回答のように失格となります。:-P
クリスジェスター-ヤング

10

この投稿の後に「ベストアンサー」を選択します。しかし、最初に、いくつかの非常に独創的な貢献を認めたいと思います。

  1. あくのもの。それぞれが、スタックオーバーフローを引き起こす新しい独自の方法を模索しています。f(x)を実行するアイデア⇒f(f(x))は、以下の次のエントリで探求するものです。:-)
  2. Nedyle コンパイラにスタックオーバーフローを与えたCodyのもの。
  3. そして、(少し不愉快なことに)、GateKillerはスタックオーバーフロー例外をスローすることについてのものです。:-P

上記を気に入っているように、課題はコードゴルフをすることであり、回答者に公平を期すために、Befungeエントリである最短のコードに「ベストアンサー」を授与する必要があります。誰もそれを打つことができるとは信じていません(ただし、Konradは確かに試しましたが)。

多数の再帰によるスタックオーバーフローソリューションを見て、誰も(現在の執筆時点で)Yコンビネーターを持ち出していないことに驚いています(入門について、Dick Gabrielのエッセイ「The Why of Y」を参照してください)。Yコンビネーターとakuのf(f(x))アプローチを使用する再帰的な解決策があります。:-)

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

8

これは、Schemeからのもう1つの興味深いものです。

((ラムダ(x)(xx))(ラムダ(x)(xx)))

とても素敵で、対称性もあります。また、(lambda(x)(xx))の公式を使用するには:((Y(lambda(x)(xx)))#f)もとても楽しいです!
Chris Jester-Young

ああ、それはきれいです。Rubyでも機能しますが、Schemeほどではありません。lambda{| x | x.call x} .call lambda {| x | x.call x}
ウェインコンラッド

7

ジャワ

Javaソリューションの少し短いバージョン。

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

5
または(同じ文字数):public static void main(String ... a){main();}
Michael Myers

またはTDDの人(同じ数の文字)の場合:public class ${@org.junit.Test public void $(){$();}}
mhaller 2009年

それでも最短ではありません(私の回答を参照)
ドラえもん


5

3バイト:

label:
  pusha
  jmp label

更新

よると(?)(?歳)インテルのドキュメント、これも3バイトです。

label:
  call label


32ビットモードでは3バイトです。スタックが私の答えよりもはるかに速くいっぱいになることを考慮して、いい答えです!
Chris Jester-Young

penguin.cz/~literakl/intel/j.html#JMPによると、jmpは3バイトで、8、16、または32ビットの相対宛先アドレスを持っています。
プッシャ

jmpには、short、near、farの3つのタイプがあります。短いjmp(0xEBオペコードを使用)は2バイトです。宛先は、次の命令から-128〜127バイト離れている必要があります。:-)
クリスジェスター-ヤング

多分あなたは正しいです。私は自分のアセンブラーを
調べて
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.