วิธีที่แปลกประหลาดที่สุดในการสร้างสแต็คล้น [ปิด]


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 แม้ว่าฉันจะรู้จักการค้นหา 'stack overflow' ในเครื่องมือค้นหาที่ฉันเลือก
OJFord

21
ใช้ Internet Explorer วิธีที่จะจับแน่นอน :)
asgoth

64
วิธีที่แปลกประหลาดที่สุดในการสร้างสแต็คโอเวอร์โฟลว์คือโพสต์การประกวดความนิยมบน codegolf.stackexchange.com เพื่อให้คนโพสต์วิธีที่แปลกประหลาดที่สุดในการสร้างสแต็คล้น ผู้เผชิญเหตุในการทดสอบวิธีแก้ปัญหาจะสร้างสแต็คล้น ฉันยังไม่ได้ทำการทดสอบดังนั้นฉันจึงไม่สามารถแน่ใจได้ว่ามันใช้งานได้ (ซึ่งเป็นสาเหตุที่ฉันไม่ได้โพสต์ไว้เป็นคำตอบ)
Tim Seguine

3
ฉันเป็นส่วนหนึ่งของวิธีนี้: joelonsoftware.com/items/2008/09/15.html
robert

11
ขับรถโตโยต้า (Hey, รอสักครู่รถของฉันคือโตโยต้า ... )
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
น่ารัก แต่ไม่ใช่สิ่งที่คำถามต้นฉบับมุ่งหวังในความคิดของฉัน
นิด

12
@Nit ฉันไม่เห็นปัญหา สิ่งที่เกี่ยวกับการแก้ปัญหานี้เป็นที่น่าพอใจ?
SimonT

17
@ masterX244 ใช่ประเด็นทั้งหมดของคำถามคือ "อย่าทำแบบปกติ"
พลูโต

24
@Plutor คุณมักจะตั้งค่า StackOverFlow ตามวัตถุประสงค์หรือไม่
กีวี

15
นี่เป็นเพียงความเฉลียวฉลาดในการโพสต์ครั้งแรกเท่านั้น
primo

189

หลาม

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

7
น่าอัศจรรย์ ดีและสง่างาม
James Webster

103
ตัวอักษรมาก คำตอบที่ดีมาก
Tim Seguine

47
นี่แสดงให้เห็นถึง Stack Overflow แต่การสร้างมันจะใช้งานได้ก็ต่อเมื่อมันคือ Jeff Atwood หรือ Joel Spolsky ที่ทำงาน
หอยทากวิศวกรรม

10
@ TimSeguine ว้าว
Sean Allred

9
ไม่ใช่คำตอบเนื่องจากไม่ได้อยู่ในเอาต์พุตข้อผิดพลาด
Pierre Arlaud

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

ผลงานโดยการเขียนทับที่อยู่ผู้ส่งจึงgกลับไปที่จุดในการก่อนที่จะเรียกmain fจะทำงานกับแพลตฟอร์มใดก็ได้ที่มีที่อยู่ผู้ส่งในกองซ้อน แต่อาจต้องปรับแต่ง

แน่นอนว่าการเขียนนอกอาร์เรย์นั้นเป็นพฤติกรรมที่ไม่ได้กำหนดไว้และคุณไม่สามารถรับประกันได้ว่ามันจะทำให้เกิดการโอเวอร์โฟลว์ของสแต็กมากกว่าที่จะบอกว่าให้ทาสีหนวดสีฟ้าของคุณ รายละเอียดของแพลตฟอร์มคอมไพเลอร์และธงการรวบรวมอาจสร้างความแตกต่างใหญ่


1
สิ่งนี้จะไม่สร้าง segfault หรือไม่
11684

4
+1 สำหรับการจัดการกองซ้อนแปลก ๆ และไม่มีการเรียกซ้ำ!
RSFalcon7

6
@ 11684 มันเป็นพฤติกรรมที่ไม่ได้กำหนดดังนั้นโดยทั่วไปแล้วมันอาจผิดพลาด บน 32 บิต Linux (ที่ฉันทดสอบ) มันเขียนนอกอาร์เรย์เขียนทับที่อยู่ผู้ส่งและไม่ผิดพลาดจนกว่าสแต็คล้น
ugoren

46
"ทาหนวดสีฟ้าของคุณ" -> บรรทัดนั้นมีฉัน
Aneesh Dogra

2
ว้าว. สิ่งนี้ทำให้งงงวยอย่างน่าอัศจรรย์
MirroredFate

108

JavaScript / DOM

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

    title = 'Kill me!';
}

หากคุณต้องการฆ่าเบราว์เซอร์ของคุณให้ลองใช้งานในคอนโซล


53
ฉันแน่ใจว่าคุณสมควรได้รับการโหวตมากกว่า 1 ครั้ง แต่คนที่น่าเศร้าลองทำสิ่งนี้ก่อนที่จะลงคะแนน .... lol
Reactgular

5
นั่นก็มีประสิทธิภาพ ฉันไม่สามารถเปิด Task Manager ของฉันเพื่อฆ่ามันได้
primo

1
ใช้ Chrome ปิดแท็บ แก้ไขปัญหา.
โคลจอห์นสัน

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

ชวา

เห็นบางสิ่งเช่นนี้อยู่แถวนี้:

แก้ไข:พบที่ฉันเห็น: Joe K คำตอบของโปรแกรม Shortest ที่พ่นข้อผิดพลาด StackOverflow

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 (... ) ซึ่งจะเรียกสายไปยัง String สิ่งนี้ทำให้การติดตามสแต็กของคุณแตกต่างกันเล็กน้อย (สามวิธีในนั้น)
Paŭlo Ebermann

2
@ PaŭloEbermannใช่นั่นถูกต้องแล้ว "" + this.toString()แต่มันเป็นเรื่องง่ายมากที่จะพูดว่ามันจะกลายเป็น
จัสติน

2
ฉันคิดว่า+ "" +เคล็ดลับอาจปิดคนเพราะดูเหมือนว่าไร้ประโยชน์ได้อย่างรวดเร็วก่อน String val;และreturn val + this;อาจจะมีเล็กน้อย sneakier
Cruncher

@Cruncher ไม่ได้เลย หากคุณเป็นจาวาโค้ด coder คุณจะรู้ว่าวิธีง่าย ๆ ในการเชื่อมสตริงเข้ากับสตริงระหว่างการ""สร้างสตริปกับ+ ""
Justin

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: มันไม่ได้ส่งผลให้เกิดการสอบถามซ้ำ ปัญหาที่ได้รับคือการระเบิดกอง ในระบบปฏิบัติการหลายระบบสแต็กมีขนาดคงที่และมีขนาดเล็กกว่าสิบล้าน ints ดังนั้นสิ่งนี้จะทำให้สแตกได้
Eric Lippert

2
@HannoBinder ใน Linux ที่ฉันทดสอบคุณจะไม่ได้รับข้อผิดพลาดของ stack overflow คุณได้รับข้อผิดพลาดในการแบ่งกลุ่มเนื่องจากการล้นสแต็กส่งผลให้สามารถเข้าถึงกลุ่มที่ไม่ได้เป็นเจ้าของ ฉันไม่แน่ใจว่ามีข้อผิดพลาดสแต็กโอเวอร์โฟลว์อยู่ใน Linux หรือไม่เนื่องจากการเรียกฟังก์ชันแบบเรียกซ้ำแบบไม่สิ้นสุดทำให้เกิดความผิดพลาดในการแบ่งกลุ่ม
Shahbaz

3
~0uมีจำนวนมากใน C.
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

JavaScript

window.toString = String.toLocaleString;
+this;

5
อันนี้ underappreciated
Ry-

1
อะไร+thisทำอย่างไร
NobleUplift

8
Unary + เรียกใช้การดำเนินการนามธรรม ToNumber ที่ใช้การดำเนินการ ToPrimitive กับชนิดของคำใบ้ ToPrimitive บนวัตถุใช้วิธีการภายใน [[DefaultValue]] ซึ่งเมื่อผ่านการบอกใบ้หมายเลขแล้วก่อนอื่นให้ตรวจสอบเพื่อดูว่ามีวิธี valueOf () อยู่และส่งกลับค่าดั้งเดิมหรือไม่ window.valueOf () คืนค่าวัตถุดังนั้น [[DefaultValue]] จะคืนค่าผลลัพธ์ของการเรียก toString () สิ่งแรกที่ window.toString ทำ (ตอนนี้มันคือ toLocaleString) ได้เรียกใช้ toString บน 'this' ทำซ้ำ
Ryan Cavanaugh

3
หาก Chrome เกิดข้อผิดพลาด 'เรียกซ้ำมากเกินไป' แสดงว่า Chrome ใช้งานได้ใช่ไหม สแต็คโอเวอร์โฟลว์และนั่นคือวิธีที่ Chrome ส่งข้อยกเว้นสแต็คโอเวอร์โฟลว์
David Conrad

4
คุณควรใช้+{toString:"".toLocaleString}:-)
Bergi

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ใด ๆ การเรียกซ้ำอยู่ภายในprintStackTrace()พฤติกรรมที่ไม่น่าสงสัยของ JDK และห้องสมุดบุคคลที่สามใด ๆ สำหรับการดีบักและบันทึกที่ใช้ในการตรวจสอบข้อยกเว้น นอกจากนี้อาจเป็นไปได้ว่าสถานที่ที่มีข้อยกเว้นถูกโยนไกลจากสถานที่ที่มีการจัดการ

อย่างไรก็ตามนี่คือรหัสที่จะส่ง a StackOverflowErrorและไม่มีการเรียกวิธีเรียกซ้ำหลังจากทั้งหมด StackOverflowErrorเกิดขึ้นนอกmainวิธีการใน JDK ของ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 stack ไอ้ชั่วร้าย! : D
Kiwy

9
ฉันมีแนวโน้มที่จะพิจารณาการสอบถามซ้ำในกรณีนี้ชัดเจน
Taemyr

1
@BlacklightShining เรียกวิธีไม่ได้ผลในการgetCause() StackOverflowErrorมันอาศัยความจริงที่ว่ามีรหัสของ JDK ซึ่งเรียกgetCause()วิธีการซ้ำ
Victor Stafusa

2
ฉันคิดว่าคุณสามารถทำให้สิ่งนี้ง่ายขึ้นโดยการเปลี่ยนเนื้อความgetCauseเป็นเพียงreturn this;แต่เห็นได้ชัดว่า Java นั้นฉลาดเกินไปสำหรับเรื่องนั้น มันสังเกตว่ามันเป็น " CIRCULAR REFERENCE"
David Conrad

1
ฉันไม่ได้รับStackOverflowErrorเพราะแพ็คเกจ OpenBSD 5.5 ของ jdk-1.7.0.21p2v0 มีข้อบกพร่อง StackOverflowErrorมันไม่โยน มันกระทบSIGSEGVและทิ้งแกน
kernigh

57

Linux x86 NASM Assembly

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: ฉันพบว่าสิ่งที่ตรงกันข้ามเป็นจริง: ในการชุมนุมทุกอย่างชัดเจนเพราะไม่มีใครสามารถใช้ abstractions เพื่อซ่อนสิ่งที่รหัสของพวกเขากำลังทำอยู่
Mason Wheeler

3
นี่คือความยอดเยี่ยมสำหรับความเรียบง่ายและความสง่างาม
haneefmubarak

11
@MasonWheeler: ฉันชอบที่จะบอกว่าทุกอย่างสามารถมองเห็นได้แทนที่จะชัดเจน ... สำหรับวิธีที่ดีที่จะเห็นความแตกต่างระหว่างการมองเห็นและชัดเจนฉันชอบที่จะอ้างอิงถึงunderhanded.xcott.com
Olivier Dulac

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)
กรุณาส่งรายงานข้อผิดพลาดแบบเต็ม
กับแหล่งที่ประมวลผลล่วงหน้าหากเหมาะสม
ดูคำแนะนำ

ไม่มีการเรียกซ้ำไฟล์ต้นฉบับนี้ไม่มีคลาสใดคลาสหนึ่งที่มีตัวเองเป็นคลาสพื้นฐานหรือแม้แต่ทางอ้อม (ใน C ++ ในเทมเพลตคลาสเช่นนี้S<1>และS<2>เป็นคลาสที่แตกต่างกันโดยสิ้นเชิง) ข้อผิดพลาดในการแบ่งเซ็กเมนต์เกิดจากการโอเวอร์โฟลว์สแต็กหลังจากเรียกซ้ำในคอมไพเลอร์


7
ฉันยอมรับว่าฉันเรียกสิ่งนี้ว่าการเรียกซ้ำซากที่เห็นได้ชัดใน metaprogram ของคุณ

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 เสียงดังกราวจับการใช้งานที่ผิดพลาด - ซึ่งฉันคิดว่าคุณรู้อยู่แล้ว - แต่มันทำให้ GCC ของฉันมีข้อความแสดงข้อผิดพลาดเกือบ 2 เมกะไบต์
Casey

4
+1 สำหรับเมตาสแต็
เกินไป

45

Bash (การแจ้งเตือนอันตราย)

while true
do 
  mkdir x
  cd x
done

พูดอย่างเคร่งครัดว่าจะไม่สแต็คโอเวอร์โฟลว์โดยตรง แต่สร้างสิ่งที่อาจระบุว่าเป็น " สถานการณ์การสร้างสแต็ก - โอเวอร์ - โฟล " แบบถาวร : เมื่อคุณรันสิ่งนี้จนกว่าดิสก์ของคุณจะเต็มและต้องการลบระเบียบด้วย "rm -rf x "ที่ถูกตี

มันไม่ได้เกิดขึ้นในทุกระบบ บางคนแข็งแกร่งกว่าคนอื่น

อันตรายใหญ่คำเตือน:

บางระบบการจัดการนี้มากไม่ดีและคุณอาจจะมีช่วงเวลาที่ยากมากในการทำความสะอาด (เพราะ "RM -rf" ตัวเองจะทำงานเป็นปัญหา recusion ก) คุณอาจต้องเขียนสคริปต์ที่คล้ายกันเพื่อล้างข้อมูล

ลองใช้วิธีนี้ในการลบ VM ถ้าไม่แน่ใจ

PS: เช่นเดียวกันแน่นอนถ้าโปรแกรมหรือทำในสคริปต์ชุด
PPS: อาจเป็นการรบกวนที่จะได้รับความคิดเห็นจากคุณว่าระบบของคุณทำงานอย่างไร ...


อย่างที่ฉันเขียน: ในหลาย ๆ ระบบ rm -rf พยายามที่จะลงไปและถูกชนหนึ่ง (อาจจะไม่อีกต่อไปในวันนี้ด้วยพื้นที่ที่อยู่ 64 บิต - แต่ในเครื่องขนาดเล็กที่มีสแต็กขนาดเล็กลงก็อาจ) แน่นอนว่าอาจมี "rm" - การดำเนินการรอบซึ่งแตกต่างกัน ...
blabla999

2
ดูเหมือนว่าฉันwhile cd x; do :; done; cd ..; while rmdir x; cd ..; done;ควรจะดูแลเรื่องนี้
แบล็กไลท์ส่องแสง

คุณพูดถูก (นั่นคือสิ่งที่ฉันหมายถึงด้วย "สคริปต์ที่คล้ายกันสำหรับการล้างข้อมูล") อย่างไรก็ตามเมื่อดิสก์ของคุณ (หรือโควต้า) เต็มคุณอาจมีเวลาในการเข้าสู่ระบบในเวลาต่อมาเนื่องจากบางระบบใช้ในการจัดการกับสถานการณ์นั้นไม่ดี คุณจะต้องเข้ารูทและทำสคริปต์ (ซึ่งเป็นเรื่องง่ายสำหรับพีซีเหล่านี้ในปัจจุบัน แต่มักจะยากในสมัยโบราณเมื่อคอมพิวเตอร์ที่ใช้โดยผู้ใช้มากกว่าหนึ่งคน)
blabla999

ตลกนี่ได้รับคะแนนมากกว่าเวทมนตร์ Smalltalk ด้านล่าง (ไม่เคยคิดเลย!)
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

ข้อยกเว้นในตัวสร้างเป็นเพียงปลาเฮอริ่งแดง นี่คือสิ่งที่หนังสือพูดถึง:

เมื่อคุณเรียกตัวสร้างให้เช่น initializers ตัวแปรทำงานก่อนที่ร่างของนวกรรมิก ในกรณีนี้ initializer สำหรับตัวแปรinternalInstanceจะเรียกคอนสตรัคเตอร์แบบเรียกซ้ำ ในทางกลับกันคอนสตรัคเตอร์ก็เริ่มต้นinternalInstanceฟิลด์ของตนเอง โดยเรียกใช้ตัวสร้าง Reluctant อีกครั้งและต่อไปเรื่อย ๆ ad infinitum การเรียกซ้ำแบบเรียกซ้ำเหล่านี้เป็นสาเหตุให้ StackOverflowErrorร่างกายของคอนสตรัคเตอร์ได้รับโอกาสในการดำเนินการ เนื่องจากStackOverflowErrorเป็นชนิดย่อยErrorมากกว่า Exceptionประโยคย่อยที่จับmainไม่ได้


41

น้ำยาง

\end\end

สแต็คการป้อนข้อมูลล้นเพราะ\endซ้ำ ๆ ขยายตัวเองในวง จำกัด ตามที่อธิบายไว้ที่นี่

TeX ล้มเหลวด้วยTeX capacity exceeded, sorry [input stack size=5000]หรือคล้ายกัน


1
ฉันกำลังรอปัญหา TeX / LaTeX สิ่งเหล่านั้นยิ่งสั่นสะเทือนกว่าปกติ - ฉันลืมไปแล้วว่าสิ่งที่ฉันทำนับเป็นรายการเมื่อจู่ ๆ ฉันก็สามารถเขียนสิ่งที่ซ้ำซากซ้ำซาก
Ernir

1
ดูเพิ่มเติมcodegolf.stackexchange.com/questions/9359/ …
bwDraco

1
"เกินความจุของ TeX ขออภัย" TeX นั้นสุภาพเมื่อล้มเหลว
Alex A.

40

BF

ในที่สุดจะล้นสแต็คเพียงแค่ขึ้นอยู่กับว่าล่ามทำให้กอง ...

+[>+]

5
รหัสนั้นทำให้ฉันนึกถึงเกมแห่งชีวิต
Adam Arold

10
อย่างเคร่งครัดพูดไม่มีกองซ้อนใน brainfuck
fejesjoco

6
@fejesjoco เทปหากคุณต้องการ
Timtech

32

C # ในเวลารวบรวม

มีหลายวิธีในการทำให้คอมไพเลอร์ Microsoft C # ระเบิดสแต็ก เมื่อใดก็ตามที่คุณเห็นข้อผิดพลาด "นิพจน์ซับซ้อนเกินกว่าจะคอมไพล์" จากคอมไพเลอร์ C # ที่เกือบจะแน่นอนเพราะสแตกได้ถูกเป่า

parser เป็นผู้สืบเชื้อสายซ้ำดังนั้นโครงสร้างภาษาที่ซ้อนกันอย่างพอเพียงจะทำให้กองซ้อน:

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

ตัวแยกวิเคราะห์นิพจน์นั้นฉลาดมากเกี่ยวกับการกำจัดการเรียกซ้ำที่ด้านข้างที่ถูกเรียกซ้ำโดยทั่วไป ปกติ:

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

ซึ่งสร้างต้นไม้ในการแยกวิเคราะห์อย่างมหาศาลจะไม่ระเบิดกอง แต่ถ้าคุณบังคับให้การเรียกซ้ำเกิดขึ้นที่อีกด้านหนึ่ง:

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

จากนั้นสแตกสามารถถูกเป่าได้

สิ่งเหล่านี้มีคุณสมบัติไม่เหมาะสมที่โปรแกรมมีขนาดใหญ่มาก นอกจากนี้ยังเป็นไปได้ที่จะทำให้ semantic analyser ไปสู่ ​​recursions ที่ไม่มีขอบเขตด้วยโปรแกรมขนาดเล็กเนื่องจากมันไม่ฉลาดพอที่จะลบรอบคี่บางอย่างในระบบประเภท (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

32

บนอินเทอร์เน็ต (ใช้งานโดยพันล้านคน / วัน)

Redirects, HTTP status code: 301

ตัวอย่างเช่นในเว็บไซต์สนับสนุนของ Dell (ไม่มีความผิดขอโทษ Dell):

หากคุณลบ TAG สนับสนุนจาก URL จากนั้นก็จะเข้าสู่ การเปลี่ยนเส้นทางที่ไม่มีที่สิ้นสุด ใน URL ต่อไปนี้ ###### เป็นแท็กสนับสนุนใด ๆ

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

ฉันเชื่อว่ามันเทียบเท่ากับกองล้น


5
วิธีที่ดี :) firefox บอกว่ามันเปลี่ยนเส้นทางดังนั้นคำขอไม่สามารถแก้ไขได้ซึ่งเป็น stackoverflow rquivalent :)
masterX244

3
โปรดทราบว่าการเปลี่ยนเส้นทางจะไม่ได้ไม่มีที่สิ้นสุด - ถ้าคุณตี "ลองอีกครั้ง" มันจะเพิ่มมากขึ้นไม่กี่/Errors/'s ไปยัง URL แล้วหยุดหลังจากที่ได้รับ HTTP 400 ร้องขอไม่ถูกต้อง แต่สิ่งนี้จะทำให้กองซ้อนล้นดีกว่าการเปลี่ยนเส้นทางแบบไม่สิ้นสุด
nandhp

@nandhp ฉันเห็นด้วย แต่ถ้าคุณคิดว่าเบราว์เซอร์โลกที่สาม (ไม่ทันสมัย ​​IE ฯลฯ .. ) พวกเขาไม่ได้รับเบาะแสเกี่ยวกับสถานการณ์นี้
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ที่นี่) เพียงเพราะอาร์เรย์นั้นลึกเกินไป (การอ้างอิงตนเอง) จากนั้นตัวรวบรวมขยะจะสิ้นสุดลงในการเรียกซ้ำ


16
GC ของ PHP ไม่สามารถตรวจจับโครงสร้างอ้างอิงตนเองได้? จริงๆ?! อุ๊ยตาย นั่นคือความชั่วร้าย
ปีเตอร์ C

1
ใช่ แต่มันไม่สมบูรณ์แบบ มีสาเหตุwhile (1) { $a = array(&$a); }บางอย่างที่คล้ายกันหรือถึงขีด จำกัด หน่วยความจำ…
bwoebi

ใช่ฉันคิดว่ามันเป็นเหตุผลเดียวกันว่าทำไม PHP ไม่ทำงานอย่างถูกต้องเกี่ยวกับการพัฒนา Object Oriented เช่นกัน (สิ่งที่เป็นนามธรรมการสืบทอด ฯลฯ )
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)

จากJava Puzzlers # 45:

สมมติว่าเครื่องของเราสามารถดำเนินการ 10 10สายต่อวินาทีและสร้าง 10 10ข้อยกเว้นต่อวินาทีซึ่งค่อนข้างใจกว้างตามมาตรฐานปัจจุบัน ภายใต้สมมติฐานเหล่านี้โปรแกรมจะยุติในเวลาประมาณ 1.7 × 10 291ปี เพื่อให้ได้มุมมองนี้อายุการใช้งานของดวงอาทิตย์ของเราจะอยู่ที่ประมาณ 10 10ปีดังนั้นจึงเป็นทางออกที่ปลอดภัยที่จะไม่มีใครอยู่ใกล้เราที่จะเห็นโปรแกรมนี้ยุติ แม้ว่ามันจะไม่วนซ้ำไม่สิ้นสุด แต่ก็อาจจะเป็นเช่นนั้น


3
การเรียกซ้ำที่ชัดเจน ... ไม่น่าสนใจมาก
คามิ

5
@Kami คุณเคยลองไหม? คุณเคยได้รับ StackOverflowError หรือไม่ ดูเหมือนชัดเจน แต่ไม่ใช่
ntoskrnl

เพียงเพราะข้อยกเว้นได้รับการติดไม่ได้หมายความว่ามันไม่เคยถูกโยน โปรแกรมนี้ส่งข้อยกเว้นสแต็กโอเวอร์
โฟลว์

1
@CodesInChaos โอเคดังนั้นฉันจึงตรวจสอบอีกครั้งและรุ่นที่ถูกต้องใช้finallyแทนcatchและเวลาทำงานคือ O (2 ^ n) อัปเดตคำตอบแล้ว
ntoskrnl

@ntorkrnl เป็นคนดีคนหนึ่ง +1 btw ได้คอมไพเลอร์เพื่อ stackoverflow แล้ว (คอมไพเลอร์ทำงานภายใน VM เกินไป fyi)
masterX244

30

C #

โพสต์แรกดังนั้นโปรดไปง่าย ๆ กับฉัน

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

สิ่งนี้จะสร้างการติดตามแบบสแต็กคว้าเฟรมด้านบน (ซึ่งจะเป็นการเรียกครั้งสุดท้ายของเราMain()) รับเมธอดและเรียกใช้งาน


วิธีที่ดีของ selfinvoke ซึ่งไม่ชัดเจนโดยไม่ต้องอธิบาย; +1 +1
masterX244

คุณควรคอมเม้นต์โค้ดด้วย "สิ่งที่อาจจะผิดพลาดได้": 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 และปวดหัวอย่างมากในการล่าสัตว์ em
masterX244

2
หากใครสงสัยรหัสเทียบเท่าใน C # ทำให้เกิดการวนซ้ำไม่สิ้นสุด แต่InnerExceptionคุณสมบัติเป็นแบบอ่านอย่างเดียวและตั้งค่าในตัวสร้างดังนั้นการสะท้อนจึงจำเป็นต้องทำให้เกิดสิ่งนี้
Athari

17

JavaScript: การกลายพันธุ์ของฟังก์ชันที่ไม่วนซ้ำและซ้ำ

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

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

ไม่มีการเรียกซ้ำที่นี่เลย fจะถูก curried ซ้ำ ๆ ด้วยอาร์กิวเมนต์ที่มากขึ้นเรื่อย ๆ จนกว่าจะสามารถล้นสแต็กในการเรียกใช้ฟังก์ชันเดียว 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());
    }
}

วิธีที่ล้มเหลวคือมหากาพย์มันทำให้ใจฉันสมบูรณ์:

ป้อนคำอธิบายรูปภาพที่นี่

มันเป็นเพียงหนึ่งเฟรมของภาพแปลก ๆ ที่ไม่มีที่สิ้นสุด

นี่จะต้องเป็นสิ่งที่แปลกประหลาดที่สุดเท่าที่เคยมีมา มีใครอธิบายได้บ้าง เห็นได้ชัดว่าการเพิ่มจำนวนของช่องว่างที่ใช้ในการเยื้องทำให้บล็อกสีขาวเหล่านั้นปรากฏขึ้น มันเกิดขึ้นใน Win7 Enterprise x64 พร้อมด้วย. NET 4.5

ฉันยังไม่เห็นจุดจบของมัน หากคุณแทนที่System.Console.Outด้วยSystem.IO.Stream.Nullมันจะตายอย่างรวดเร็ว

คำอธิบายนั้นง่ายมาก ฉันสร้างคลาสที่มีคุณสมบัติเดียวและจะส่งคืนอินสแตนซ์ใหม่ของประเภทที่มีอยู่เสมอ ดังนั้นมันจึงเป็นลำดับชั้นของวัตถุที่ลึกอย่างไม่ จำกัด ตอนนี้เราต้องการบางสิ่งที่พยายามอ่านสิ่งนั้น นั่นคือสิ่งที่ฉันใช้XmlSerializerซึ่งทำอย่างนั้น และเห็นได้ชัดว่ามันใช้การสอบถามซ้ำ


ใช่; ทำให้เป็นอันดับ ftw: P; แต่ตลกมากขึ้นก็คือเมื่อการเล่นโวหารของคุณอยู่นอกรหัสของคุณเช่นวิธีที่งูได้รับคุณลักษณะและชั้นหนึ่งคืนตัวเองในทางที่ซ้ำซาก endlesly
masterX244

1
การล้นเกิดขึ้นนอกรหัสของฉัน แต่สาเหตุที่แท้จริงที่ฉันโพสต์นี้เป็นเพราะผลข้างเคียงที่ไม่คาดคิดในคอนโซล :-)
fejesjoco

ฉันคิดว่าบิตสีขาวจะต้องทำอย่างไรกับ. Net 4.5 หรือวิธีการตั้งค่าสภาพแวดล้อมของคุณเพราะใช้. Net 4 (แม้เมื่อทำงานผ่าน cmd) ฉันได้รับช่องว่างเท่านั้นไม่มีบล็อกสีขาว ฉันเดาว่าทั้ง Win7 Enterprise รุ่น cmd หรือ. NET 4.5 คอนโซลอีมูเลเตอร์ใช้อักขระบางตัวผสมกันเป็น 'เปลี่ยนพื้นหลังสีคอนโซล'
Pharap

ฉันไม่สามารถทำซ้ำได้ด้วย. NET 4.5 บน Win7 x64 Professional โดยเปิด Aero
Ray

ทำซ้ำไม่ได้เช่นกัน .NET 4.5, Windows 8.1 Pro
bwDraco

13

ทุบตี

_(){ _;};_

ในขณะที่หลายคนอาจจำได้ว่าการเรียกซ้ำเป็นสิ่งที่ชัดเจนแต่ดูเหมือนว่าสวย ไม่มี?

เมื่อดำเนินการคุณจะได้รับการรับประกันในการดู:

Segmentation fault (core dumped)

5
อันนี้สวยกว่าและแย่กว่า:_(){_|_;};_
RSFalcon7

1
@ การแจ้งเตือน RSFalcon7 Forkbomb! (นอกจากนี้มันไม่จำเป็นต้องมีช่องว่างหลังจากที่{จะถูกต้อง syntactically?)
Blacklight Shining

3
ลองสิ่งนี้เช่นกัน:(){:|:;}:
Tarek Eldeeb

14
ดูเหมือนอิโมติคอนที่น่าขนลุกและกลายพันธุ์
Tim Seguine

8
Bash emoticons: ผู้กินใบหน้า, นักฆ่ากองหน้า
NobleUplift

12

Haskell

( แต่เป็นความจริงที่น่าเศร้าอย่างน้อยก็จนกว่าghc-7.6แม้ว่าจะมีO1หรือมากกว่าก็จะเพิ่มประสิทธิภาพของปัญหาที่เกิดขึ้นไป)

main = print $ sum [1 .. 100000000]

ไม่ควรทำการเพิ่มประสิทธิภาพการโทรหางโดยอัตโนมัติ (รวม)?
blabla999

2
@ blabla999: การโทรหางนั้นไม่เกี่ยวข้องกับ Haskell แต่ส่วนใหญ่จะเป็นสิ่งที่สะสมเนื่องจากความขี้เกียจแอบแฝงที่ก่อให้เกิดปัญหาดังกล่าว ในกรณีนี้ปัญหานี้sumมีการนำมาใช้ในแง่ของfoldlซึ่งใช้หางเรียก แต่เนื่องจากมันไม่ได้ประเมินการสะสมอย่างเคร่งครัดเพียงแค่สร้างกองของ thunks ที่มีขนาดใหญ่เท่ากับรายการต้นฉบับ ปัญหาจะหายไปเมื่อเปลี่ยนไปที่จะfoldl' (+)ประเมินอย่างเคร่งครัดและส่งคืน WHN ในการเรียกหาง หรืออย่างที่ฉันพูดถ้าคุณเปิดการปรับให้เหมาะสมของ GHC!
หยุดที่จะเปลี่ยนรหัสผ่านเมื่อ

aah - น่าสนใจดังนั้นถ้าไม่มีใครรอให้อันธพาล (เช่นออกจากพิมพ์) ตัวเก็บขยะจะรวบรวมพวกเขาออกไป (จากด้านหน้าไปด้านหลัง)?
blabla999

1
BTW ไม่มีสิ่งใดที่ระบุไว้อย่างแท้จริงตามมาตรฐาน Haskell: เพียง แต่ต้องการการประเมินที่ไม่เข้มงวดเช่นการคำนวณแบบไม่สิ้นสุดจะไม่ปิดกั้นตลอดไปหากผลลัพธ์ไม่ต้องการอย่างเต็มที่ ระยะเวลาที่บล็อกขึ้นอยู่กับการนำไปใช้จริงใน G ขี้เกียจมาตรฐานจะไม่บล็อกเลยจนกว่าคุณจะขอผลลัพธ์
หยุดที่จะเปลี่ยนรหัสผ่านเมื่อ

2
Haskell เย็น
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...

PS: มีการเพิ่ม "withoutUpdatingChangesFile:" เพื่อหลีกเลี่ยงการล้างข้อมูลแฟ้มบันทึกการเปลี่ยนแปลงถาวรของ Smalltalk หลังจากนั้น

PPS: ขอบคุณสำหรับความท้าทาย: การคิดเกี่ยวกับสิ่งใหม่และนวัตกรรมคือความสนุก!

PPPS: ฉันชอบที่จะทราบว่าภาษาถิ่น / เวอร์ชันของ Smalltalk คัดลอกเฟรมสแต็กล้นไปยังฮีป - ดังนั้นสิ่งเหล่านี้อาจทำงานในสถานการณ์ที่หน่วยความจำไม่พอแทน


2
LOL +1 สำหรับเวทมนต์ดำนั้นในรูปแบบบริสุทธิ์
masterX244

หากฉันพบบางเวลาฉันอาจ "ปรับปรุง" โดยใช้วิธีการไม่ระบุชื่อของคลาสนิรนามเพื่อสร้างหลุมกระต่ายที่มืดที่สุดตลอดกาล ...
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

มันจะดูเหมือนการเรียกซ้ำ แต่เป็นไปได้ด้วยข้อโต้แย้งประเภทซ้อนกัน
ja72

1
ไม่เห็นคำตอบ C # struct ของคุณก่อนที่ฉันจะโพสต์ของฉัน ฉันยังคงมีวิธีที่แตกต่างกันเล็กน้อยดังนั้นบางทีเราปล่อยให้พวกเขาอยู่ร่วมกัน
Thomas Weller

11

C #

การใช้งานที่ผิดพลาดของตัวดำเนินการแบบ overriden ==:

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 มัน

มันขึ้นอยู่กับผู้อ่านที่จะหาวิธีการทำงาน: P (เคล็ดลับ: stackoverflow.com)

โดยวิธีการ: การเรียกซ้ำจะทำแบบไดนามิกโดย SnakeYAML (คุณจะสังเกตเห็นว่าคุณรู้วิธีการตรวจจับเขตข้อมูลที่มันทำให้เป็นอันดับและดูในPointซอร์สโค้ดของ)

แก้ไข: บอกวิธีการทำงาน:

SnakeYAML ค้นหาคู่ของgetXXXและsetXXXmthod ที่มีชื่อเดียวกันสำหรับXXXและ return type ของ getter เหมือนกับพารามิเตอร์ของ setter และน่าประหลาดใจที่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
IMHO นี่คือตัวอย่างคลาสสิกสำหรับการเรียกซ้ำที่ชัดเจน ... (และไม่ถูกต้อง)
Ole Albers

2
เห็นได้ชัดก็ต่อเมื่อคุณทำเสร็จแล้วและคิดว่า C # getters ไม่ทำงานอย่างที่คุณคิด ท้ายที่สุดรหัสนี้คือการประกาศตัวแปรสมาชิกดังนั้นทำไมมันไม่ควรสร้างตัวแปรสมาชิกจริง?
meustrus

2
นี่ไม่ใช่วิธีการที่ซับซ้อนที่จะทำได้static void Main() { Main(); }
Jodrell

5
@Jodrell คุณจะไม่เขียนซ้ำMain()โดยไม่ตั้งใจ แต่มันค่อนข้างง่ายในการเขียนคุณสมบัติแบบเรียกซ้ำโดยไม่ตั้งใจและจากนั้นจะเกิดความสับสนโดยสแต็กล้น
svick

1
สิ่งนี้จะเป็นประโยชน์สำหรับคนที่รับ C #
2rs2ts
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.