スタックオーバーフローを生成する最も奇妙な方法[終了]


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 14

21
Internet Explorerを使用します。1つをキャッチする確実な方法:)
asgoth 14

64
スタックオーバーフローを生成する最も奇妙な方法は、人々にスタックオーバーフローを生成する最も奇妙な方法を投稿するように求める人気コンテストをcodegolf.stackexchange.comに投稿することです。レスポンダーは、質問に対するソリューションをテストする際に、スタックオーバーフローを引き起こします。私はそれをテストしていませんでしたので、私はそれが動作することを確認することはできません(それが私が答えとしてそれを投稿しなかった理由です)。
ティムセギーン14

3
私はこの方法に部分的です:joelonsoftware.com/items/2008/09/15.html-
ロバート

11
トヨタを運転してください(ちょっと待ってください、私の車トヨタです...)
squeamish ossifrage 14

回答:


224

Python

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 14

17
@ masterX244はい、質問の要点は「通常の方法でやらない」です。
Plutor 14

24
@Plutorは通常、意図的にStackOverFlowをセットアップしますか?
キウィ14

15
これは初めて投稿されたときにはわずかに賢いだけでした
primo 14

189

Python

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

7
素晴らしい。素敵でエレガント。
ジェームズウェブスター14

103
多くの文字通り。非常に答えます。
ティムセギーン14

47
さて、これスタックオーバーフローを示していますが、1つを生成するためには、Jeff AtwoodまたはJoel Spolskyがそれを実行している場合にのみ機能します。
機械式カタツムリ14

10
@TimSeguineうわー。
ショーンオールレッド14

9
エラー出力にはないため、回答ではありません。
ピエールアラード14

131

C / Linux 32ビット

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

戻りアドレスを上書きすることで機能します。したがってgmainを呼び出す前にポイントに戻りますf。リターンアドレスがスタック上にあるすべてのプラットフォームで機能しますが、微調整が必​​要になる場合があります。

もちろん、配列外への書き込みは未定義の動作であり、口ひげを青く塗るなどしてスタックオーバーフローを引き起こす保証はありません。プラットフォーム、コンパイラ、およびコンパイルフラグの詳細は、大きな違いを生む可能性があります。


1
これはセグメンテーション違反を引き起こしませんか?
11684

4
奇妙なスタック操作と絶対に再帰しないための+1!
RSFalcon7

6
@ 11684、未定義の動作なので、一般的にクラッシュする可能性があります。32ビットLinux(私がテストした)では、配列の外側に書き込み、戻りアドレスを上書きし、スタックがオーバーフローするまでクラッシュしません。
ウゴレン

46
「口ひげを青く塗る」->その行には私がいた。
Aneesh Dogra

2
ワオ。これは見事に難読化されています。
MirroredFate 14

108

JavaScript / DOM

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

    title = 'Kill me!';
}

ブラウザを強制終了したい場合は、コンソールで試してみてください。


53
私はあなたがより多くの1票に値すると確信しているが、悲しいことに人々が投票前にこれを試してみました....笑
Reactgular

5
まあ、それは効果的でした。タスクマネージャを開いて強制終了することもできませんでした。
primo

1
Chromeを使用して、タブを閉じます。問題が解決しました。
コールジョンソン14

1
with (document.body) { addEventListener('DOMSubtreeModified', function() { appendChild(firstChild); }, false); title = 'Kill me!'; } 15:43:43.642 TypeError: can't convert undefined to object
ブライアンミントン14

1
くそー、私のFirefoxが絞首刑になった
ファハド

91

Java

この辺りをどこかで見ました:

編集:私がそれを見た場所を見つけました:StackOverflowエラーをスローする最短プログラムに対するジョーKの答え

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

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

これは、一部のJava初心者を混乱させる可能性があります。単に再帰呼び出しを非表示にします。val + thisが文字列であるval + this.toString()ためになりvalます。

ここで実行してください:http : //ideone.com/Z0sXiD


30
実際には、それは行われnew StringBuilder().append(val).append("").append(this).toString()、最後の追加はString.valueOf(...)を呼び出し、それがtoStringを呼び出します。これにより、スタックトレースが少し変化します(3つの方法があります)。
パエロエベルマン

2
@PaŭloEbermannええ、それは正しいです。ただし、になると言う方がはるかに簡単"" + this.toString()です。
ジャスティン14

2
私が思うに+ "" +、それは一見無用に見えるよう、かもしれないチップの人々をオフにします。String val;そしてreturn val + this;わずかsneakierかもしれない
たけ

@Cruncherはまったくありません。Javaのコーダーであれば、""-Stringの構築中にintを文字列に連結する簡単な方法は、+ ""
ジャスティン14

5
実際のアプリケーションでは、私は無限の再帰とスタックオーバーフローエラーを回避することを好む
jon_darkstar

77

C

結構簡単:

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

10
明らかでない場合は+1!それは非常にシステムに依存しているにもかかわらず(ulimit -s unlimitedシェルでは、Linuxでこれを解決します)
RSFalcon7

4
@ RSFalcon7、+ 1に感謝しますが、私にとってこれは実際に最も明白でした!!
Shahbaz

14
@Cruncher:再帰は発生しません。与えられた問題は、スタックを爆破することでした。多くのオペレーティングシステムでは、スタックのサイズは固定されており、1000万intよりもはるかに小さいため、スタックが破壊されます。
エリックリッパー14

2
@HannoBinder、私がテストしたLinuxでは、スタックオーバーフローエラーは発生しません。スタックをオーバーフローさせると、所有されていないセグメントにアクセスするため、セグメンテーション違反が発生します。Linuxにスタックオーバーフローエラーが存在するかどうかはわかりません。無限の再帰的な関数呼び出しでもセグメンテーションエラーが発生するからです。
シャーバズ14

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ことを期待し、呼び出し先がそれを行うことを期待するため、型キャスト関数ポインターを介して呼び出すことにより、クリーンアップは行われません- main各呼び出しでパラメーターをスタックにプッシュしますが、最終的には何もポップしませんスタックがいっぱいになります。


2
スタックをスパムする良い方法:P
masterX244 14

62

JavaScript

window.toString = String.toLocaleString;
+this;

5
これは過小評価されています。
Ry- 14

1
何を+thisするの?
NobleUplift

8
単項+は、ToNumber抽象操作を呼び出します。これは、ヒントタイプの数値でToPrimitive操作を使用します。オブジェクトのToPrimitiveは[[DefaultValue]]内部メソッドを使用します。このメソッドは、数値ヒントを渡すと、最初にvalueOf()メソッドが存在するかどうかを確認し、プリミティブを返します。window.valueOf()はオブジェクトを返すため、代わりに[[DefaultValue]]はtoString()を呼び出した結果を返します。window.toStringが最初に行うこと(今ではtoLocaleStringである)は、「this」でtoStringを呼び出します。繰り返す。
ライアンキャバノー14

3
Chromeで「再帰が多すぎます」というエラーがスローされた場合、Chromeで動作しますか?スタックがオーバーフローし、それがChromeがスタックオーバーフロー例外を配信する方法です。
デビッドコンラッド14

4
使用する必要があります+{toString:"".toLocaleString}:-)
ベルギ14

62

以前の回答 Java 7とJava 8が悪のコードから免れているという事実にイライラしていました。そこで、そのためのパッチが必要であると判断しました。

成功!私はprintStackTrace()スローを作りましたStackOverflowErrorprintStackTrace()デバッグとロギングに一般的に使用されており、それが危険であると合理的に疑う人はいません。このコードが悪用されて深刻なセキュリティ問題が発生する可能性があることを確認するのは難しくありません。

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バージョンのstackoverflow準拠のメソッド。邪悪な野郎!:D
Kiwy 14

9
この場合の再帰は明白だと考えたいです。
Taemyr

1
@BlacklightShiningメソッドを呼び出しても、getCause()は発生しませんStackOverflowErrorgetCause()メソッドを再帰的に呼び出すJDKのコードがあるという事実に依存しています。
ビクターStafusa 14

2
本文をJava getCauseだけに変更することでこれを単純化できると思ったreturn this;が、どうやらJavaはそれに対して賢すぎる。「CIRCULAR REFERENCE」であることがわかります。
デビッドコンラッド14

1
StackOverflowErrorjdk-1.7.0.21p2v0のOpenBSD 5.5パッケージにバグがあるため、私は入手できませんでした。投げないStackOverflowError。ヒットしSIGSEGV、コアをダンプします。
カーニグ

57

Linux 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:私は反対が真実だと思います:アセンブリでは、誰も抽象化を使用してコードが実際に行っていることを隠すことができないため、すべてが明白です。
メイソンウィーラー14

3
これは、そのシンプルさとエレガンスのために素晴らしいです。
ハネフムバラク14

11
@MasonWheeler:私はすべてがあると言うことを好む見える目に見えると明らかに違いを見るために良い方法については、私はを参照してくださいが大好き...ではなく明らかunderhanded.xcott.com
オリヴィエ・デュラック

2
私は忘却の私の頻繁な過ちを覚えてret
ルスラン

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)
完全なバグレポートを送信してください。
必要に応じて、前処理されたソースで。
手順についてはを参照してください。

このソースファイルの再帰はありません。クラスの1つがそれ自体を基本クラスとして持っているわけではなく、間接的にもありません。(C ++では、このようなテンプレートクラスで、S<1>かつS<2>完全に別個のクラスである。)セグメンテーション違反は、コンパイラに再帰後スタックオーバーフローに起因します。


7
私はこれをあなたのメタプログラムの明白な再帰と呼んでいたと告白します。

2
GCCは再帰を検出し、こちら側を正常に停止します(4.8以上は問題ないようです)
アレックティール14

2
template <typename T> auto foo(T t) -> decltype(foo(t)); decltype(foo(0)) x;少し短いです。
ケーシー14

2
@hvd GCCのバグを悪用しているようです。clangは誤った使用法をキャッチします -既に知っていると思いますが-私のGCCはほぼ2メガバイトのエラーメッセージを吐き出します。
ケーシー14


45

Bash(危険アラート)

while true
do 
  mkdir x
  cd x
done

厳密に言えば、直接スタックオーバーフローすることはありませんが、「永続的なスタックオーバーフローの生成状況」とラベル付けされるものを生成します。これをディスクがいっぱいになるまで実行し、「rm -rf x "、その1つがヒットします。

ただし、すべてのシステムで発生するわけではありません。他のものよりも堅牢なものもあります。

大きな危険警告:

一部のシステムはこれを非常に不適切に処理し、クリーンアップに非常に苦労する場合があります(「rm -rf」自体が異常な問題に遭遇するため)。クリーンアップするには、同様のスクリプトを作成する必要があります。

よくわからない場合は、スクラッチVMでこれを試してください。

PS:もちろん、バッチスクリプトでプログラムまたは実行された場合も同様です。
PPS:特定のシステムの動作、あなたからコメントを得るのは興味深いかもしれません...


私が書いたように:多くのシステムで、rm -rfはダウンしようとし、1つにヒットします(最近では、64ビットのアドレス空間ではないかもしれませんが、スタックが小さい小さなマシンではそうかもしれません)。もちろん、また違っそれを行うの周りに「RM」-implementationsを、...があるかもしれません
blabla999

2
私のように何かwhile cd x; do :; done; cd ..; while rmdir x; cd ..; done;がこれを大事にする必要があります。
ブラックライトシャイニング14

あなたは絶対に正しいです(これは、「クリーンアップ用の類似スクリプト」で私が意図したことです)。ただし、ディスク(またはクォータ)がいっぱいになると、一部のシステムがその状況にうまく対処していなかったため、後でログインするのに苦労することさえあります。rootとしてログインしてスクリプトを実行する必要があります(今日のこれらのPCでは簡単ですが、古代ではコンピューターが複数のユーザーによって使用されていたため、しばしば困難でした)。
blabla999 14

面白いことに、これは以下のSmalltalkマジックよりも多くの票を獲得します(考えたことはありません!)
blabla999 14

誰かがWindowsでこれを試しましたか?
セージボルシュ14

43

Java

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はコンストラクターを再帰的に呼び出します。そのコンストラクターはinternalInstance、Reluctantコンストラクターを無限に繰り返し呼び出すなどして、独自のフィールドを初期化し ます。これらの再帰呼び出しによりStackOverflowError、コンストラクター本体が実行の機会を得る前にaが発生します 。のでStackOverflowErrorのサブタイプであるErrorのではなく Exception、中のcatch句はmainそれをキャッチしません。


41

ラテックス

\end\end

ここで\end説明するように、無限ループで繰り返し自身を展開するため、入力スタックがオーバーフローします

TeXは、a TeX capacity exceeded, sorry [input stack size=5000]または同様のもので失敗します。


1
TeX / LaTeXの問題を待っていました。これらのことはほとんどの場合よりも不快です-通常、私は突然無限に再帰的な何かを書くことができたときに、自分がしていることをプログラミングとして数えることを忘れていました。
エルニール14


1
「TeXの容量を超えました、申し訳ありません」 TeXは失敗したときとても礼儀正しい。
アレックスA.


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)です。このエラーメッセージのドキュメントはこちらにあり、まさにあなたの言うとおりです:「コードを処理するコンパイラにスタックオーバーフローがありました。」
bwDraco 14

32

インターネット (1日あたり10億人が使用)

Redirects, HTTP status code: 301

たとえば、DellサポートWebサイト(違反なし、ごめんなさいDell):

URLからサポートTAGを削除すると、 無限リダイレクトになります。次のURLで、######はサポートTAGです。

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

スタックオーバーフローと同等だと思います。


5
素敵な方法:) firefoxはリダイレクトするので、リクエストは解決できないため、stackoverflow rquivalent :)
masterX244 14

3
リダイレクトは無限ではないことに注意してください。「Try Again」を/Errors/押すと、URLにさらにが追加され、HTTP 400 Bad Requestを受信した後に停止します。しかし、これは間違いなく無限リダイレクトよりも優れたスタックオーバーフローをもたらします。
nandhp 14

@nandhp、私は同意しますが、第三世界のブラウザー(現代、IEなどではない)を考えると、彼らはこの状況の手がかりを持っていません。
codeSetter 14

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/...
ボルティコ14

31

PHP

ループ要素のみで行われるスタックオーバーフロー。

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

説明(スポイラーを見ること):

インタープリターが$tmp配列をガベージコレクションしようとすると($tmpここで再割り当てするとき)、プログラムはセグメンテーション違反を起こします。配列が深すぎる(自己参照)ために、ガベージコレクターが再帰的になります。


16
PHPのGCは自己参照構造を検出できませんか?本当に?!痛い。それ悪です。
ピーターC 14

1
はい、でも完璧ではありません。なぜいくつかの理由がありますwhile (1) { $a = array(&$a); }だけでメモリの上限に達するか、似た何かが...
bwoebi

うん、PHPもオブジェクト指向開発に関して適切に機能していないのと同じ理由だと思います。(抽象化、継承など)
pythonian29033 14

1
@ pythonian29033細心の注意が必要ですか?
vvondra 14年

30

Java

私はまったく逆のことを行いました。明らかに、スタックオーバーフローエラーをスローするはずのプログラムですが、そうではありません。

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

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

ヒント:プログラムはO(2 n)時間で実行され、nはスタックのサイズ(通常は1024)です。

以下からのJavaのpuzzlers#45:

私たちのマシンが毎秒10 10コールを実行し、毎秒10 10の例外を生成できると仮定しましょう。これは現在の標準ではかなり寛大です。これらの仮定の下では、プログラムは約1.7×10 291年で終了します。これを視野に入れると、太陽の寿命は10 10年と推定されるため、このプログラムが終了するのを見るために誰もいないというのは安全な賭けです。それは無限ループではありませんが、そうかもしれません。


3
明らかな再帰...あまり面白くない。
神14

5
@Kami試したことある?実際にStackOverflowErrorが発生しましたか?明らかですが、そうではありません。
ntoskrnl

例外がキャッチされたからといって、例外がスローされなかったわけではありません。このプログラムは、時間O(N)の後に、スタックオーバーフロー例外をスロー
CodesInChaos

1
@CodesInChaosわかりましたので、これを再確認しました。正しいバージョンではfinallyでなくを使用してcatchおり、実行時間はO(2 ^ n)です。回答が更新されました。
NTOSKRNL

@ntorkrnl素敵なものに+ 1'd; ところで、すでにStackOverflowのようにコンパイラ(コンパイラはあまりにもFYI、VMの内部で実行)だ
masterX244

30

C#

最初の投稿ですので、私に簡単に行ってください。

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

これは単にスタックトレースを作成し、一番上のフレーム(最後の呼び出しMain())を取得し、メソッドを取得して呼び出します。


説明せずに自明ではない自己呼び出しの素敵な方法。+
1'd

あなたは「?何がおそらく間違って行くことができる」とそのコードコメントすべきである:Pを
宇宙飛行士

26

Java

  • 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
ええ; 何もないからのスタックオーバーフローは、コードトローリングのベストフレンドであり、emを狩る上で深刻な頭痛の種です
masterX244 14

2
誰もが疑問に思うなら、C#の同等のコードは無限ループを引き起こします。ただし、InnerExceptionプロパティは読み取り専用であり、コンストラクターで設定されるため、これを引き起こすにはリフレクションが必要です。
アサリ14

17

JavaScript:非再帰的な反復関数の突然変異

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());
    }
}

それが失敗する方法は壮大です、それは私の心を完全に吹き飛ばしました:

ここに画像の説明を入力してください

これは、一見無限に見える奇妙な一連の画像のほんの1フレームです。

これは、これまでで最も奇妙なことでなければなりません。誰でも説明できますか?どうやら、インデントに使用されるスペースの量が増え続けると、それらの白いブロックが表示されます。.NET 4.5を搭載したWin7 Enterprise x64で発生します。

私は実際にそれの終わりを見ていません。あなたが交換した場合System.Console.OutSystem.IO.Stream.Null、それはかなり速く死にます。

説明はとても簡単です。単一のプロパティを持つクラスを作成します。このクラスは常に、含まれる型の新しいインスタンスを返します。したがって、これは無限に深いオブジェクト階層です。今、それを読み通そうとするものが必要です。それが私が使用する場所でXmlSerializer、まさにそれを行います。そして、明らかに、再帰を使用します。


ええ; ftw:P;のシリアル化 ythe癖がsnakeyaml属性を取得する方法のように、あなたのコードの完全に外側にあり、1つのクラスがendlesly再帰的な方法で自分自身を返すときにはもっと面白いことをある
masterX244

1
まあ、オーバーフローは私のコードの外で起こりますが、私がこれを投稿した本当の理由は、コンソールの予期しない副作用のためです:
fejesjoco 14

.Net 4.5を使用するか、環境を設定する方法のどちらかである必要があると思います。なぜなら、.Net 4を使用すると(cmdを実行した場合でも)、スペースのみが得られ、ホワイトブロックは得られないからです。私の推測では、Win7 Enterpriseバージョンのcmdまたは.Net 4.5コンソールエミュレーターは、特定の文字の組み合わせを「コンソールの色の背景の変更」として扱います。
ファラプ14

私はエアロとWin7のx64のプロフェッショナルに.NET 4.5でそれを再現することはできませんオン
レイ

再現することもできません。.NET 4.5、Windows 8.1 Pro。
bwDraco 14年

13

バッシュ

_(){ _;};_

多くの人が再帰が明らかであることを認識するかもしれませんが、それはかなりのようです。番号?

実行すると、以下が表示されます。

Segmentation fault (core dumped)

5
これはきれいと悪いです:_(){_|_;};_
RSFalcon7

1
@ RSFalcon7 Forkbombアラート!(また、{構文的に正しいためにはスペースが必要ではありませんか?)
Blacklight Shining 14

3
これも試してください:(){:|:;}:
タレクエルディーブ14

14
不気味な、突然変異体の絵文字のように見えます。
ティムセギーン14

8
Bash絵文字:顔を食べる人、スタックを殺す人。
NobleUplift

12

ハスケル

(悲しいが、少なくともghc-7.6O1それ以上であれば問題を最適化するまでは真)

main = print $ sum [1 .. 100000000]

末尾呼び出しの最適化を自動的に(まとめて)行うべきではありませんか?
blabla999 14

2
@ blabla999:テールコールはHaskellではそれほど重要ではありません。そのような問題を引き起こしているのは秘密の怠zyによるサンクの蓄積です。この場合、問題は末尾呼び出しを使用してsum実装されますがfoldl、アキュムレータを厳密に評価しないため、元のリストと同じ大きさのサンクの山を厳密に生成するだけです。この問題は、に切り替えると解消foldl' (+)され、厳密に評価されるため、末尾呼び出しでWHNを返します。または、私が言ったように、GHCの最適化を有効にすると!
反時計回りに14

ああ-興味深いので、サンクを待つ人がいない場合(つまり、プリントを除外する場合)、ガベージコレクターはそれらを(前から後ろに)収集しますか?
blabla999 14

1
ところで、これは実際にはHaskell標準では指定されていません。評価が非厳密であることが必要なだけです。つまり、結果が完全に必要でない場合、終了しない計算は永久にブロックされません。実際にブロックする時間は実装次第です。標準の遅延GHCでは、結果を要求するまでブロックしません。
反時計回りに14

2
haskellはクールです。
blabla999

12

Smalltalk

これにより、新しいメソッドがオンザフライで
  作成され、新しいメソッドがオンザフライで
    作成され、新しいメソッドがオンザフライで作成され、
      ...
    ...
  ..
に転送されます。

余分な小さなスパイスは、スタックメモリとヒープメモリに同時にストレスをかけることによってもたらされます。これは、より長いメソッド名とより長いメソッド名の両方を作成し、レシーバーとして膨大な数を作成することにより、穴に落ちたときに...(ただし、再帰が最初にヒットします)。

整数でコンパイル:

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...

PS:Smalltalkの永続的な変更ログファイルを後でクリーンアップする必要を避けるために、「withoutUpdatingChangesFile:」が追加されました。

PPS:挑戦してくれてありがとう:新しくて革新的な何かについて考えるのは楽しかったです!

PPPS:一部のSmalltalk方言/バージョンでは、オーバーフローするスタックフレームがヒープにコピーされるため、メモリ不足の状態に陥る可能性があることに注意してください。


2
その黒魔術の純粋な形でLOL +1
masterX244 14

私はいくつかの時間を見つけた場合、私が今までに...暗いウサギの穴にするために、匿名クラスの匿名メソッドを使用して「改善する」こと
blabla999

12

C#

本当に大きく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>>>>();
    }
}

より一般的なコード手段が必要:P
NPSF3000 14

再帰のように見えますが、ネストされた型の引数で可能です。
ja72

1
私が私の投稿する前にあなたのC#構造体の答えを見ませんでした。私はまだ少し異なるアプローチを持っているので、多分それらを共存させました。
トーマスウェラー14

11

C#

オーバーライドされた==演算子の実装の誤り:

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==を使用して自分自身を呼び出すことは明らかであると言うかもしれません==が、通常はそのように考えていない==ので、そのintoに陥りやすいです。


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は、一対探しgetXXXsetXXXで同じ名前でmthod XXXとゲッターの戻り値の型は、セッターのパラメータと同じです。そして驚くべきことに、PointクラスにはがありPoint getLocation()void setLocation(Point P)それはそれ自体を返します。SnakeYAMLはそれに気づかず、その癖とStackOverflowsを繰り返します。内部で彼らと働いて、そのHashMap上でstackoverflow.comに尋ねると、それを発見しました。


10

C#

誤って実装されたプロパティゲッター

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

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

14
私見では。これは明らかな再帰の古典的な例です...(したがって無効です)
オレアルバース

2
まあ、一度やったことがあるのは明らかで、C#ゲッターが思ったように動作しないことがわかりました。結局のところ、このコードはメンバー変数宣言なので、実際のメンバー変数を作成しないのはなぜですか?
meustrus 14

2
これは複雑な方法にstatic void Main() { Main(); }
すぎ

5
@Jodrell Main()誤って再帰を書くことはないでしょう。しかし、誤って再帰的なプロパティを記述し、スタックオーバーフローによって混乱するのは非常に簡単です。
svick 14

1
これは、C#を拾う人にとって便利です。
2rs2ts
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.