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


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.