Yığın taşması üretmenin en garip yolu [kapalı]


146

Bir programcı olarak, bariz bir özyinelemeden dolayı yığın taşması hatasını kesinlikle biliyorsunuzdur. Ancak en sevdiğiniz dili bu hatayı gidermek için kullanabileceğiniz çok garip ve sıradışı yollar var.

Amaç:

  1. Hata çıktısında açıkça görülebilen bir yığın taşmasına neden olmalıdır.
  2. Belirgin bir özyineleme kullanmasına izin verilmiyor.

Geçersiz programlara örnekler:

// Invalid, direct obvious recursion.
methodA(){ methodA(); }
// Invalid, indirect, but obvious recursion.
methodA(){ methodB(); }
methodB(){ methodA(); }

En yaratıcı yollar, bu için en iyisidir . Yani, bunun gibi bariz cevapları sıkmaktan kaçının:

throw new StackOverflowError(); // Valid, but very boring and downvote-deserving.

Şimdi bir cevap kabul etmeme rağmen, daha fazla cevap eklemek hala sorun değil :)


14
Seçtiğim arama motorumda 'yığın taşması'nı sorguladığım biliniyor olsa da stackoverflow.com adresine giderek üretim yapma eğilimindeyim.
OJFord

21
Internet Explorer'ı kullanın.
Birini

64
Bir yığın taşması oluşturmanın en garip yolu, bir yığın taşması oluşturmanın en garip yolunu göndermelerini isteyen bir kod yarışması yapmak için codegolf.stackexchange.com adresindeki popülerlik yarışmasını yayınlamaktır. Yanıtlayanlar, soruya çözümlerini test ederken yığın taşması üretecektir. Yine de test etmedim, bu yüzden çalıştığından emin olamıyorum (bu yüzden cevap olarak göndermedim).
Tim Seguine

3
Bu yönteme kısmi olarak: joelonsoftware.com/items/2008/09/15.html
robert

11
Bir Toyota Sürücü (arabam, Hey, bir dakika bekleyin olduğunu ... bir Toyota)
alıngan ossifrage

Yanıtlar:


224

piton

import sys
sys.setrecursionlimit(1)

Bu, tercümanın derhal başarısız olmasına neden olacaktır:

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

Özyineleme kullanmak yerine, yığını hemen küçülecek şekilde küçültür.


12
Sevimli, ama bence orijinal soru neyi hedefliyordu.
Nit

12
@Nit Sorunu görmüyorum. Peki ya bu çözüm tatmin edici değil?
SimonT

17
@ masterX244 Evet, sorunun asıl amacı "her zamanki gibi yapma" dır.
Plutor

24
@Plutor, genellikle bilerek bir StackOverFlow kurar mı?
Kiwy


189

piton

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

7
Fantastik. Güzel ve şık.
James Webster

103
Çok edebi. Çok cevap.
Tim Seguine

47
Bu bir Yığın Taşması gösterir , ancak bir tane üretmek için , bu yalnızca Jeff Atwood veya Joel Spolsky tarafından çalıştırılıyorsa çalışır.
Mekanik salyangoz,

10
@ TimSeguine Vay.
Sean Allred

9
Hata çıktısında olmadığı için cevap değil.
Pierre Arlaud

131

C / Linux 32bit

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

İade adresinin üzerine yazarak çalışır, Bu yüzden aramadan önce go noktaya geri döner . İade adreslerinin yığında olduğu herhangi bir platform için çalışacak, ancak tweaks gerektirebilir.mainf

Tabii ki, bir dizinin dışına yazmak tanımsız bir davranıştır ve bıyık mavinizi boyamak yerine yığma taşmasına neden olacağının garantisi yoktur. Platform, derleyici ve derleme bayraklarının detayları büyük bir fark yaratabilir.


1
Bu bir segfault üretmez mi?
11684

4
Garip yığın manipülasyonu için +1 ve kesinlikle tekrarlama yok!
RSFalcon7

6
@ 11684, Bu tanımsız davranış, bu yüzden genel olarak çökebilir. 32 bit Linux'ta (üzerinde test ettiğim), dizinin dışına yazar, dönüş adresinin üzerine yazar ve yığın taşana kadar çökmez.
Şubat'ta ugoren

46
"Bıyığını mavi boya" -> O çizgide beni vardı.
Aneesh Dogra

2
Vay. Bu fevkalade karışıktır.
MirroredFate

108

JavaScript / DOM

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

    title = 'Kill me!';
}

Tarayıcınızı öldürmek istiyorsanız, bunu konsolda deneyin.


53
Daha fazla +1 oy
hakkını aldığına

5
Bu etkili oldu. Görev yöneticimi öldürmek için bile açamadım.
primo

1
Chrome'u kullanın, sekmeyi kapat. Sorun çözüldü.
Cole Johnson,

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
Lanet olsun Firefox asıldı
Farhad

91

Java

Buralarda bir yerde böyle bir şey gördüm:

Düzenleme: Gördüğüm yerde bulundu: Joe K'nin StackOverflow Hatası veren kısa programın cevabı

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

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

Bu bazı Java yeni başlayanlarını şaşırtabilir. Sadece özyinelemeli çağrıyı gizler. val + thisolur val + this.toString()çünkü valbir String.

Burada çalıştığını görün: http://ideone.com/Z0sXiD


30
Aslında bunu yapar new StringBuilder().append(val).append("").append(this).toString()ve son ekleme, sıraylaString'i çağıran String.valueOf (...) öğesini çağırır. Bu, Stack izlemenizi biraz değiştirir (orada üç yöntem).
Paŭlo Ebermann

2
@ PaŭloEbermann Evet, doğru. Ancak, olduğunu söylemek çok daha kolaydır "" + this.toString().
Justin,

2
Sanırım, + "" +insanlar ilk bakışta işe yaramaz göründüğü için insanları rahatsız edebilir. String val;ve return val + this;marjinal olarak daha sinsi olabilir
Cruncher

@Cruncher hiç değil. Eğer bir Java kodlayıcısıysanız, ""-String yapımı sırasında bir dizgeye int kullanmanın kolay yolunun -String yapımı sırasında+ ""
Justin

5
Gerçek bir dünya uygulamasında sonsuz özyinelemeden kaçınmayı ve taşma hatalarını önlemeyi tercih ederim
jon_darkstar

77

C

Oldukça kolay:

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

10
Açık olmayan için +1! Çok sisteme bağlı olmasına rağmen (bir ulimit -s unlimitedkabuk bunu
linux'da

4
@ RSFalcon7, +1 için teşekkürler, ama bana göre bu aslında en belirgin !!
Shahbaz

14
@Cruncher: Özyinelemeyle sonuçlanmaz. Verilen sorun yığını patlatmaktı. Birçok işletim sisteminde istif sabit boyuttadır ve on milyon inçten çok daha küçüktür, bu yüzden yığını istila eder.
Eric Lippert

2
@HannoBinder, Test ettiğim Linux'ta yığın taşması hatasıyla karşılaşmıyorsunuz. Yığın taşması, istenmeyen bölümlere erişime neden olduğu için bir bölümleme hatası alıyorsunuz. Sonsuz bir özyinelemeli işlev çağrısı da bir bölümleme hatası verdiğinden, Linux'ta yığın taşması hatasının oluşup oluşmadığından emin değilim.
Shahbaz

3
~0uC oldukça büyük bir sayıdır
Vortico

63

Özyinelemeyen yığın taşması C

Çağrılan kongre uyuşmazlığı.

typedef void __stdcall (* ptr) (int);

void __cdecl hello (int x) { }

void main () {
  ptr goodbye = (ptr)&hello;
  while (1) 
    goodbye(0);
}

İle derleyin gcc -O0.

__cdeclfonksiyonlar arayanın yığını temizlemesini bekler ve arayanın yapmasını __stdcallbekler, bu yüzden typecast işlevi imlecini çağırarak temizleme işlemi asla yapılmaz - mainparametreyi her arama için yığına iter ancak hiçbir şey çıkarmaz ve sonuçta yığın doldurur.


2
yığını spam göndermenin güzel bir yolu: P
masterX244

62

JavaScript

window.toString = String.toLocaleString;
+this;

5
Bu bir takdir edilmez.
Ry

1
Ne yapar +this?
NobleUplift

8
Unary +, ToNumber soyut işlemini başlatır. Bu, ToPrimitive işlemini bir ipucu türü numarasıyla kullanır. Bir Nesne Üzerindeki ToPrimitive, [[DefaultValue]] dahili yöntemini kullanır; bu, bir sayı ipucunu geçtiğinde, valueOf () yönteminin var olup olmadığını ve ilkeli döndürdüğünü görmek için önce denetler. window.valueOf () bir nesne döndürür, bunun yerine [[DefaultValue]], toString () öğesini çağırmanın sonucunu döndürür. Window.toString'in yaptığı ilk şey (şimdi bunun için, LocalString'dir) 'this' deString'i çağırır. Tekrar et.
Ryan Cavanaugh

3
Chrome bir hata atarsa, 'Çok fazla özyineleme' varsa, Chrome'da çalışır, değil mi? Yığın taşması ve Chrome'un yığın taşması istisnası vermesidir.
David Conrad

4
Kullanmanız gereken +{toString:"".toLocaleString}:-)
Bergi

62

Java 7 ve Java 8'in önceki cevabımdaki kötülük koduma karşı bağışık olmaları beni çok etkiledi . Böylece bunun için bir yamanın gerekli olduğuna karar verdim.

Başarı! printStackTrace()Atıp attım StackOverflowError. printStackTrace()genellikle hata ayıklama ve kayıt için kullanılır ve hiç kimse bunun tehlikeli olabileceğinden şüphelenmez. Bazı ciddi güvenlik sorunları oluşturmak için bu kodun kötüye kullanılabileceğini görmek zor değil:

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

Bazı insanlar bunun bariz bir özyineleme olduğunu düşünebilir. O değil. EvilExceptionYapıcı çağırır gelmez getCause()bu durum aslında tüm sonra güvenle atılan böylece, yöntem. getCause()Yöntemin çağrılması StackOverflowErrorikisinde de sonuçlanmaz . Özyineleme, JDK'nın normalde beklenmeyen printStackTrace()davranışları ve istisnayı incelemek için kullanılan hata ayıklama ve kayıt için kullanılan 3. parti kitaplığın içindedir . Ayrıca, istisnanın atıldığı yerin, kullanıldığı yerden çok uzakta olması muhtemeldir.

Neyse, işte a atan StackOverflowErrorve özyinelemeli yöntem çağrıları içermeyen bir kod . StackOverflowErrorDışarıda olup mainJDK en içinde, yöntemin 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 ve şimdi bir çapraz java sürüm stackoverflow uyumlu yöntemle. Kötü piç! : D
Kiwy

9
Bu durumda özyinelemeyi açık bir şekilde dikkate almaya meyilliyim.
Taemyr

1
@BlacklightShining Metodun çağrılması getCause()sonuçlanmaz StackOverflowError. Bir JDK kodunun tekrarlı olarak getCause()yöntemi çağıran kodunun bulunmasına dayanıyor .
Victor Stafusa,

2
Sana gövdesini değiştirerek bu basitleştirmek düşündüm getCausesadece kadar return this;ama görünüşe Java bunun için çok zeki. Bir " CIRCULAR REFERENCE" olduğunu fark eder .
David Conrad

1
Ben alamadım StackOverflowErrorjdk-1.7.0.21p2v0 ait OpenBSD 5.5 paketi bir hata var çünkü. Atmaz StackOverflowError. SIGSEGVÇekirdeği vurur ve atar.
kernigh

57

Linux x86 NASM Birleşimi

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

Bir şeyin önceden reklamı:

PrintHello'dan dönmeyi unutmak, böylece tekrar _start'a atlayacağız.


78
Montajda hiçbir şey açık değildir.
11684

21
@ 11684: Aksini doğru buluyorum: montajda her şey açıktır çünkü hiç kimse kodlarının gerçekte ne yaptığını gizlemek için soyutlamalar kullanamaz.
Mason Wheeler

3
Bu sadeliği ve zarafeti için mükemmel.
haneefmubarak

11
@MasonWheeler: Ben bariz yerine her şeyin görünür olduğunu söylemeyi tercih ederim ... Görünen ile bariz arasındaki farkı görmenin güzel bir yolunu görmek için underhanded.xcott.com
Olivier Dulac

2
Unutma sık sık yaptığım hatalarımı hatırlıyorumret
Ruslan

48

Derleme zamanında 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 ++: dahili derleyici hatası: Segmentasyon hatası (cc1plus programı)
Lütfen tam bir hata raporu gönderin,
uygunsa önceden işlenmiş kaynak ile.
Talimatlar için bakınız.

Bu kaynak dosyada özyineleme yoktur, sınıflardan birinin dolaylı olarak bile temel sınıf olduğu söylenemez. (C ++ 'ta böyle bir şablon sınıfında S<1>ve S<2>tamamen farklı sınıflardır.) Segmentasyon hatası, derleyicide özyinelemeden sonra yığın taşmasından kaynaklanır.


7
İtiraf ediyorum, bunu metaprogramında açık bir özyineleme olarak adlandırırdım.

2
GCC, özyinelemeyi algılar ve bu tarafa zarafetle durur (4.8 ve üstü iyi görünüyor)
Alec Teal

2
template <typename T> auto foo(T t) -> decltype(foo(t)); decltype(foo(0)) x;biraz daha kısa.
Casey,

2
@hvd GCC’de bir böceği istismar ediyor gibi görünüyor. clang , zaten farkında olduğunuzu varsaydığım hatalı kullanımı yakalar - ancak GCC'mi neredeyse 2 megabayt hata mesajı yaymaktadır.
Casey,

4
Yığın taşması için +1 : p
Aschratt

45

Bash (Tehlike Uyarısı)

while true
do 
  mkdir x
  cd x
done

Açıkça söylemek gerekirse, bu doğrudan taşma yapmaz, ancak " sürekli akışa neden olan bir yığın oluşturma durumu " olarak etiketlenebilecek olanı oluşturur : bunu diskiniz doluncaya kadar çalıştırdığınızda ve karışıklığı kaldırmak istediğinizde "rm -rf x ", bu çarptı.

Yine de, tüm sistemlerde gerçekleşmez. Bazıları diğerlerinden daha sağlam.

Büyük tehlike UYARI:

Bazı sistemler bunu çok fena şekilde ele alır ve temizlik için çok zaman harcayabilirsiniz (çünkü "rm -rf" kendiliğinden bir problemle karşılaşacaktır). Temizlemek için benzer bir komut dosyası yazmanız gerekebilir.

Emin değilseniz çizik bir VM'de bunu daha iyi deneyin.

Not: Aynı şey, bir toplu komut dosyasında programlanmış veya yapılmışsa da geçerlidir.
PPS: Sizden bir yorum almak, sisteminizin nasıl çalıştığını yorumlamak ...


Yazdığım gibi: birçok sistemde, rm -rf aşağı inmeye çalışır ve bir kişi tarafından vurulur (belki de bugünlerde, 64bit adres alanına sahip - ama daha küçük yığına sahip daha küçük makinelerde olabilir). Tabii ki, aynı zamanda "rm" - etrafında farklı uygulamalar yapan uygulamalar da olabilir ...
blabla999

2
Görünüşe göre bunun gibi bir şey while cd x; do :; done; cd ..; while rmdir x; cd ..; done;olmalı.
Blacklight Shining

Kesinlikle haklısın ("temizlik için benzer komut dosyası" ile kastediyorum). Ancak, diskiniz (veya kotanız) dolduktan sonra, bazı sistemler bu durumla başa çıkmak için kullanıldıkları için oturum açmakta zorlanabilirsiniz. Kök olarak girmeniz ve senaryoyu yapmanız gerekir (bu, bugünün bilgisayarlarında kolaydır, ancak bilgisayarların birden fazla kullanıcı tarafından kullanıldığı yerlerde eski zamanlarda çok zordu).
blabla999

komik, bu aşağıdaki Smalltalk büyüsünden daha fazla oy alır (bunu hiç düşünmedim!)
blabla999

Birisi bunu Windows'ta denedi mi?
Sarge Borsch

43

Java

Java Puzzlers'dan hoş bir kitap . Ne yazdırıyor?

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

Bir StackOverflowError ile başarısız oluyor.

Yapıcıdaki istisna, sadece kırmızı bir ringa balığı. Kitabın bu konuda söylediği şey bu:

Bir yapıcı çağırdığınızda, example değişken başlatıcıları , yapıcının gövdesinden önce çalışır . Bu durumda, değişken için başlatıcı, internalInstanceyapıcıyı yinelemeli olarak çağırır. Bu yapıcı, sırayla, internalInstanceisteksiz kurucuyu tekrar ve benzeri şekilde, adin sonsuz olarak çağırarak kendi alanını başlatır . Bu özyinelemeli çağrılar StackOverflowError, kurucu birimin yürütme şansını yakalamadan önce olur. Çünkü StackOverflowErrorbir alt tür Errorolduğundan Exception, catch cümlesi mainonu yakalamaz.


41

Lateks

\end\end

Giriş yığını taşar, çünkü burada\end açıklandığı gibi sürekli olarak sonsuz bir döngüde kendini genişletir .

TeX, a TeX capacity exceeded, sorry [input stack size=5000]veya benzeri ile başarısız olur .


1
Bir TeX / LaTeX sorunu bekliyordum. Bu şeyler çoğundan daha sıkıntılı - genellikle, yaptığım şeyin, aniden sonsuz özyinelemeli bir şeyler yazmayı başardığımda programlama olarak sayıldığını unuttum.
Ernir


1
"TeX kapasitesi aşıldı, üzgünüm" TeX başarısız olduğunda çok kibar.
Alex A.

40

BF

Sonunda yığının üzerinden taşar, tercümanın yığını ne kadar sürdüğüne bağlıdır ...

+[>+]

5
Bu kod bana hayat oyununu hatırlatıyor.
Adam Arold

10
Açıkça konuşursak, beyninde hiçbir yığın yoktur.
fejesjoco

6
@ Fejesjoco Bant, isterseniz.
Timtech

32

C #, derleme zamanında

Microsoft C # derleyicisinin yığınını uçurmasına neden olmanın birkaç yolu vardır; C # derleyicisinden aldığınız "ifade derlemek için çok karmaşık" bir hata gördüğünüzde neredeyse kesinlikle yığının uçması nedeniyle oluşuyor.

Ayrıştırıcı özyinelemeli iniş, bu nedenle yeterince derinlemesine yuvalanmış herhangi bir dil yapıları yığını mahveder:

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

İfade ayrıştırıcısı, genellikle yinelenen taraftaki özyinelemeleri ortadan kaldırma konusunda oldukça akıllıdır. Genelde:

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

Son derece derin bir ayrıştırma ağacı oluşturan, yığını üflemeyecek. Fakat özyinelemeyi diğer tarafta olmaya zorlarsanız:

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

sonra yığın üflenebilir.

Bunlar, programın çok büyük olması, inelegant özelliğine sahiptir. Ayrıca semantik analizörün küçük bir programla sınırlandırılmamış özyinelemelere girmesi de mümkündür, çünkü tip sistemdeki bazı garip döngüleri ortadan kaldıracak kadar akıllı değildir. (Roslyn bunu geliştirebilir.)

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? 

Bu analizin neden sonsuz bir özyinelemeye girdiğini anlatıyorum:

http://blogs.msdn.com/b/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx

ve daha birçok ilginç örnek için bu makaleyi okumalısınız:

http://research.microsoft.com/en-us/um/people/akenn/generics/FOOL2007.pdf


2
Kesin hata mesajı fatal error CS1647: An expression is too long or complex to compile near (code). Bu hata iletisinin belgeleri burada ve tam olarak dediğiniz gibi: "Kodunuzu işleyen derleyicide bir yığın taşması oldu."
bwDraco

32

İnternette (milyar kişi / gün tarafından kullanılır)

Redirects, HTTP status code: 301

Örneğin, Dell destek web sitesinde (alınma, özür dilerim Dell):

Destek TAG’sini URL’den kaldırırsanız, sonsuz yönlendirmelere girilir . Aşağıdaki URL’de ######, herhangi bir destek TAG’ıdır.

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

Yığın taşmasına eşdeğer olduğuna inanıyorum.


5
nice way :) firefox yeniden yönlendirdiğini söyler böylece istek çözülemez, hangisi yığınsal akış olur :)
masterX244

3
Yönlendirmeleri olduğunu unutmayın değil sonsuz - Eğer "Yeniden Dene" birkaç daha ekler vurursanız /Errors/'ın URL'ye ve sonra HTTP 400 Bad Request aldıktan sonra durur. Fakat bu tartışmasız, sonsuz bir yönlendirmenin yaptığından daha iyi bir yığın taşması sağlar.
nandhp

@nandhp, katılıyorum, ancak üçüncü bir dünya tarayıcısının (modern değil, IE vb.) olduğunu düşünüyorsanız, bu durumla ilgili bir ipucu bulamadılar.
codeSetter

2
İşte Wget burada nasıl yanıt veriyor: 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

Yalnızca döngü öğeleriyle yapılan bir yığın akışı.

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

Açıklama (spoiler görmek için hover):

Tercüman, çöpü $tmpdiziyi toplamaya çalıştığında ( $tmpburada yeniden atama yaparken ) program farklılaşacaktır . Sırf dizinin çok derin olması (kendi kendine referans) ve çöp toplayıcı bir özyinelemeyle sonuçlanır.


16
PHP'nin GC'si kendini yönlendiren yapıları algılayamıyor mu? Gerçekten mi?! Ahh. Yani bir kötülük.
Peter C,

1
Evet, ama mükemmel değil. Bunun while (1) { $a = array(&$a); }ya da benzeri bir şeyin sadece hafıza sınırına
ulaşması

evet, PHP'nin Nesne Yönelimli geliştirme ile ilgili düzgün çalışmamasının aynı nedeni olduğunu düşünüyorum; (soyutlama, miras vb.)
pythonian29033

1
@ pythonian29033 ayrıntılandırmak ister misiniz?
vvondra

30

Java

Tam tersini yaptım - açıkça bir yığın taşma hatası atması gereken, ancak yapmayan bir program.

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

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

İpucu: program O (2 n ) sürede çalışır ve n yığının boyutudur (genellikle 1024).

Gönderen Java puzzlers # 45:

En makinemiz 10 yürütebileceği düşünelim 10 saniyede görüşmeleri ve 10 oluşturmak 10 akım standartlarına göre oldukça cömert saniyede istisnalar. Bu varsayımlara göre, program yaklaşık 1.7 × 10 291 yıl içinde sona erecektir . Bu perspektif koymak için, bizim güneşin ömrü 10 olarak tahmin ediliyor 10 yıldır, bu yüzden hiçbirimiz bu program sona görmeye etrafında olacak bir sakınca yoktur. Sonsuz bir döngü olmasa da, olabilir.


3
Açıkça özyinelemede ... çok ilginç değil.
Kami

5
@Kami Denediniz mi? Gerçekten bir StackOverflowError aldın mı? Açık görünüyor, ama değil.
ntoskrnl

Sadece bir istisna yakalandığı için asla atılmadığı anlamına gelmez. Bu program, O (n) saatinden sonra yığın taşması istisnası atar
CodesInChaos

1
@CodesInChaos Tamam, bu yüzden bunu iki kez kontrol ettim ve doğru sürüm finallyyerine kullanıyor catchve çalışma süresi 0 (2 ^ n). Cevap güncellendi.
ntoskrnl

@ntorkrnl nice one + 1'd; btw derleyiciyi zaten
yığın akışına getirdi

30

C #

İlk gönderi, lütfen beni rahatça takip edin.

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

Bu basitçe bir yığın izlemesi yaratır, üst kareyi alır (bu bizim son çağrımız olacak Main()), yöntemi alır ve onu çağırır.


açıklama yapmadan açıkça belli olmayan selfinvoke'nin güzel yolu; +
1'dü

Bu kodu "neyin yanlış gidebilir?"
Spaceman

26

Java

  • Java 5'te, printStackTrace()sonsuz bir döngüye girer.
  • Java 6'da, printStackTrace()atar StackOverflowError.
  • Java 7 ve 8'de düzeltildi.

Çılgınca olan şey, Java 5 ve 6'da kullanıcı kodundan gelmemesi, JDK kodunda gerçekleşmesi. Kimse printStackTrace(), yürütülmesi tehlikeli olabileceğinden şüphelenmiyor .

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
Evet; hiçbir şeyden istifleme akışı, codetrolling için en iyi arkadaş ve avlanmada ciddi bir baş ağrısıdır
masterX244

2
Herkes merak ediyorsa, C # 'daki eşdeğer kod sonsuz bir döngüye neden olur. Ancak InnerExceptionözellik salt okunurdur ve yapıcıya ayarlanır, bu nedenle buna yansıması gerekir.
Athari,

17

JavaScript: Özyinelemeli olmayan, tekrarlamalı fonksiyon mutasyonu

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

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

Burada hiçbir özyineleme yok. tek bir işlev çağrısındaf yığının dışına taşana kadar sürekli ve daha fazla argüman ile tekrar tekrar körüklenecektir . console.logBölüm durumda bunu yapmak için kaç argüman görmek istiyorum isteğe bağlıdır. Ayrıca akıllı JS motorlarının bunu optimize etmemesini sağlar.

CoffeeScript'te kod-golf sürümü, 28 karakter:

f=->
do f=f.bind f,1 while 1

14

Destansı bir başarısızlıkla 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());
    }
}

Başarısızlık şekli epik, aklımı başımdan aldı:

görüntü tanımını buraya girin

Bu görünüşte sonsuz görünen bir tuhaf resim dizisinin sadece bir karesidir.

Bu şimdiye kadarki en garip şey olmalı. Herhangi biri açıklayabilir mi? Görünüşe göre, girinti için kullanılan sürekli artan boşluk, bu beyaz blokların görünmesine neden olmaktadır. Win7 Enterprise x64'te .NET 4.5 ile gerçekleşir.

Aslında henüz sonunu görmedim. Eğer değiştirirseniz System.Console.Outile System.IO.Stream.Null, oldukça hızlı ölür.

Açıklama oldukça basittir. Tek bir özelliğe sahip bir sınıf yapıyorum ve her zaman içerdiği türün yeni bir örneğini döndürür. Bu yüzden sonsuz derinlikte bir nesne hiyerarşisi. Şimdi bunu okumaya çalışan bir şeye ihtiyacımız var. Kullandığım XmlSerializeryer orası. Ve görünüşe göre, özyinelemeyi kullanır.


Evet; ftw serileştirme: P; ama daha komik olanı, tuhaflığın kodunuzun dışında snakeyaml'in nasıl nitelikleri kazandığı ve bir sınıfın kendini zorlayacak şekilde geri döndürdüğü gibi bir kodun dışına çıkmasıdır.
masterX244

1
Eh, taşma
kodumun

Beyaz bitlerin .Net 4.5 ile ya da ortamınızın nasıl kurulduğuyla ilgili olması gerektiğini düşünüyorum. Tahminime göre, Win7 Enterprise sürümünün cmd'si veya .Net 4.5 konsol öykünücüsü, 'konsol rengi arka planını değiştir' olarak belirli bir karakter kombinasyonunu ele alıyor.
Pharap

Win7 x64 Professional'daki Aero 4.5 ile Aero açıkken yeniden
Ray

Üreme de yok. .NET 4.5, Windows 8.1 Pro.
bwDraco

13

darbe

_(){ _;};_

Birçoğu özyinelemenin açık olduğunu kabul etse de , oldukça iyi görünüyor. Hayır?

Yürütme sonrasında şunları görmeniz garanti edilir:

Segmentation fault (core dumped)

5
bu bir daha güzel ve daha kötüsü:_(){_|_;};_
RSFalcon7

1
@ RSFalcon7 Forkbomb uyarısı! (Ayrıca, {sözdizimsel olarak doğru olması için bir alana ihtiyaç duymaz mı?)
Blacklight Shining

3
Bunu da deneyin:(){:|:;}:
Tarek Eldeeb 17:14

14
Ürpertici, mutant bir ifade gibi görünüyor.
Tim Seguine

8
Baş ifadeleri: yüz yiyici, yığın katili.
NobleUplift

12

Haskell

(üzgün ama gerçek en azından ghc-7.6, gerçi O1ya da daha fazlası ile sorunu ortadan kaldıracak olsa bile )

main = print $ sum [1 .. 100000000]

otomatik olarak bir kuyruk çağrısı optimizasyonu yapmamalı mı (toplamda)?
blabla999

2
@ blabla999: kuyruk aramaları Haskell ile alakalı değil, çoğunlukla bu tür sorunlara neden olan gizli tembellikten dolayı thunk birikimi. Bu durumda, mesele yani sumaçısından uygulanan foldlkuyruk aramaları kullanmak işlevi gören, ancak akümülatörü değerlendirmek olmadığı için kesinlikle sadece orijinal listeden kadar büyük thunks bir yığın üretir. Geçiş yaparken foldl' (+), kesinlikle katı bir şekilde değerlendirilen ve böylece kuyruk çağrısı sırasında bir WHN döndüren problem ortadan kalkar . Veya, dediğim gibi, GHC'nin optimizasyonlarını açarsanız!
saat

aah - ilginç, eğer kimse sopayı bekleyemezse (yani baskıyı bırakarak), çöp toplayıcı onları (önden arkaya) toplar mı?
blabla999

1
BTW, bunların hiçbiri Haskell standardı tarafından gerçekten belirtilmemiştir: değerlendirmenin kesin olmaması şarttır , yani sonuç tam olarak gerekli değilse, belirsiz bir hesaplama sonsuza dek engellemeyecektir . Gerçekte ne kadar engellediği, uygulamanın ne kadar sürdüğünü, standart tembel GHC'de, sonucu talep edene kadar hiçbir şekilde engellemiyor.
saat

2
Haskell harika.
blabla999

12

Smalltalk

Bu, anında yeni bir yöntem oluşturur, anında
  yeni bir yöntem oluşturur, anında
    yeni bir yöntem oluşturur, bu da
      ...
    ...
  ..
ve sonra ona aktarılır.

Ekstra küçük bir baharat, hem daha uzun hem de daha uzun bir yöntem adı ve aynı zamanda delikten düştüğümüzde alıcı olarak büyük bir sayı yaratarak yığın hafızasını VE yığın belleği aynı anda zorlamaktan gelir ... ).

Tamsayı içinde derleme:

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.

sonra zıplayarak, değerlendirerek "2 downTheRabbitHole"...
... bir süre sonra, bir RecursionException'ı gösteren bir hata ayıklayıcısına sahip olacaksınız.

O zaman tüm pisliği temizlemelisiniz (hem SmallInteger hem de LargeInteger artık pek çok harikalar diyarı koduna sahip):

{SmallInteger . LargeInteger } do:[:eachInfectedClass |
    (eachInfectedClass methodDictionary keys 
        select:[:nm| nm startsWith:'downTheRabbitHole_'])
            do:[:each| eachInfectedClass removeSelector:each]

ya da tarayıcıda biraz zaman harcayarak Alice'in harikalar diyarını kaldırabilirsiniz.

İşte iz başından bazıları:

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

Not: daha sonra Smalltalk'ın kalıcı değişiklik günlüğü dosyasını temizlemek zorunda kalmamak için "withoutUpdatingChangesFile:" eklendi.

PPS: meydan okuma için teşekkürler: yeni ve yenilikçi bir şeyler düşünmek eğlenceliydi!

PPPS: Bazı Smalltalk lehçelerinin / sürümlerinin taşan yığın karelerini yığına kopyaladığını - bu nedenle bunun yerine yetersiz bellek durumuna yol açabileceğini unutmayın.


2
Saf haliyle bu kara büyü için LOL +1
masterX244

Biraz zaman bulursam, anonim bir sınıfın anonim bir yöntemini kullanarak "şimdiye kadar en karanlık tavşan deliğini açmak için" geliştirebilirim ...
blabla999

12

C #

Gerçekten büyük struct, özyineleme yok, saf C #, güvensiz kod değil.

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

bir vurucu olarak bunu belirten hata ayıklama pencereleri çöküyor {Cannot evaluate expression because the current thread is in a stack overflow state.}


Ve genel sürüm (NPSF3000 önerisi için teşekkürler)

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

Daha fazla bilgiye ihtiyaç var Genel kod
metinleri

Özyinelemeye benzeyecek, ancak iç içe geçmiş argümanlarla mümkündür.
ja72

1
Benimkini göndermeden önce C # yapı cevabı görmedim. Hala biraz farklı bir yaklaşımım var, bu yüzden onların bir arada yaşamalarına izin verdik.
Thomas Weller

11

C #

Geçersiz kılınan ==operatörün hatalı uygulaması :

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

Birisi operator==, ==operatörü kullanarak kendisini aramanın açık olduğunu söyleyebilir , ancak genellikle böyle düşünmüyorsunuz ==, bu yüzden bu tuzağa düşmek kolaydır.


11

SnakeYAML kullanarak cevap vermeye başlamak

class A
{

    public static void main(String[] a)
    {
         new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point());
    }
}

Düzenleme: ungolfed onu

Bunun nasıl çalıştığını öğrenmek okuyucuya kalmış: P (tip: stackoverflow.com)

Bu arada: özyineleme SnakeYAML tarafından dinamik olarak yapılır (serileştirdiği alanları nasıl algıladığını bilir ve Pointkaynak koduna bakarsanız fark edeceksiniz )

Düzenleme: Bunun nasıl çalıştığını söylemek:

SnakeYAML , aynı adı taşıyan bir çift getXXXve mthod arar ve alıcı türünün geri dönüş türü, ayarlayıcının parametresiyle aynıdır; ve şaşırtıcı bir şekilde sınıf sahiptir ve kendisi döndürür; SnakeYAML bunu fark etmiyor ve bu ilginç ve StackOverflow'ları tekrar ediyor. İçinde onlarla çalışırken ve üzerinde stackoverflow.com'u sorurken bunu keşfetti.setXXXXXXPointPoint getLocation()void setLocation(Point P)HashMap


10

C #

yanlış uygulanmış mülk alıcı

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

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

14
BENİM NACİZANE FİKRİME GÖRE. Bu bariz bir özyinelemeye klasik bir örnektir ... (ve bu yüzden geçerli değil)
Ole Albers

2
Sadece bir kez yaptıktan ve C # alıcılarının yaptıklarını düşündüğünüz gibi çalışmadıklarını anladıktan sonra belli oluyor. Sonuçta, bu kod bir üye değişkeni bildirimidir, öyleyse neden gerçek bir üye değişkeni yaratmasın?
meustrus

2
Bu, alışılmışın dışında bir yoldan başka bir şey değilstatic void Main() { Main(); }
Jodrell

5
@Jodrell Main()Yanlışlıkla özyinelemeli yazmazsınız . Ancak yanlışlıkla özyinelemeli bir özellik yazmak oldukça basittir ve ardından yığın taşması ile karıştırılmamalıdır.
svick

1
Bu, C # alan birisi için faydalı olacaktır.
2
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.