引发StackOverflow错误的最短程序


75

编写一个程序,该程序会引发StackOverflow错误或所用语言的等效语言。例如,在Java中,程序应抛出java.lang.StackOverflowError

您不允许定义一个调用自身或新类的函数mainjava中包含的类除外)。它应该使用所选编程语言的类。

并且它不应显式抛出错误。


4
我不理解“使用所选编程语言的类”
约翰·卫斯理亲王

3
可以定义一个这样调用内部函数的函数def s{def t=s;t}吗?
约翰·卫斯理亲王

12
在大多数语言中,类只是一种特殊的数据结构,而不是宇宙的中心。许多人甚至没有这样的东西。

1
有趣的是,需要消除尾递归的语言(以及在不需要语言时支持尾递归的实现)(实际上更好)在此方面处于劣势。TwiNight的答案链接到早期就存在于Stack Overflow上的版本。
dmckee 2013年

1
来自Java文档:当堆栈溢出发生时抛出,因为应用程序递归过深。 docs.oracle.com/javase/6/docs/api/java/lang/…–
jsedano

Answers:


90

Befunge,1岁

我不认识Befunge,但是...

1

从堆栈溢出代码高尔夫


21
说明:1是一个数字文字,当遇到时会被压入堆栈。在Befunge中,控制流回绕直到遇到@结束程序。
histocrat

6
我不知道StackOverflow上有这个问题。发布前,我仅在该网站上进行过搜索。
True Soft

31
我很高兴在这里看到我的答案。
帕特里克

4
这也适用于> <>。
Cruncher

49

Python(2.7.3),35个字符

import sys
sys.setrecursionlimit(1)

此操作本身成功完成,但是脚本和交互都会因此而立即抛出RuntimeError: 'maximum recursion depth exceeded'

受elssar的回答启发。


我考虑将其作为解决方案,但是不确定该错误是否可以视为堆栈溢出。虽然从本质上讲就是这样,对吗?
elssar 2013年

2
@elssar:我想有两种方法可以使堆栈溢出:增大堆栈的已使用部分,或减小堆栈的未使用部分。如果您想象水桶装满水,则可以通过添加更多的水来使水桶溢出,但是也可以通过收缩水桶使水桶溢出。

19

辅酶Q

Compute 70000.

70000只是S (S ( ... (S O) ...))70000 S的语法糖。我认为是导致堆栈溢出的类型检查器。

这是在执行命令之前打印的警告:

Warning: Stack overflow or segmentation fault happens when working with large
numbers in nat (observed threshold may vary from 5000 to 70000 depending on
your system limits and on the command executed).

2
这可能会让您认为Coq是一种非常愚蠢的语言...有趣的是
不再转动计数器时钟了

1
@leftaroundabout其实不是。Nat类型是类型级别的peano数字,必须像它是一个链表一样起作用。
FUZxxl 2013年

1
@FUZxxl:我的评论一点也不讽刺。自己决定是否要在那句话中加入古典逻辑,还是宁愿保持建设性...
不再是反时钟了

2
@leftaroundabout糟糕,抱歉。我忘记了降价解析器总是吃那些漂亮的&lt; irony&gt;标签。
FUZxxl

19

爪哇-35

class S{static{new S();}{new S();}}

OP没说没有新课吗?我public static void main在那里看不到。还是我只是不懂Java?
Braden Best

4
@ B1KMusic没有新课程,只有一个课程(S)。该代码使用静态初始化程序,它会在jvm找出没有main方法之前抛出SO。适用于
Java6。– aditsu

1
我了解静态块。但是下一个块是什么?
Nicolas Barbulesco 2014年

1
@NicolasBarbulesco这是一个初始化程序块,在构造新实例时执行。
aditsu

1
@LuigiCortese我认为它仅适用于Java 6或更早版本
–aditsu

19

Javascript 24个字符

浏览器相关的答案(必须有权访问apply):

eval.apply(0,Array(999999))
  • eval 是我能找到的最短的全局函数名称(有人知道哪个更短吗?)
  • apply允许我们将数组转换为函数参数,第一个参数是函数的上下文(this
  • Array(999999)将使用列出的长度创建一个数组。不确定参数的最大数量是多少,但小于此数量且大于99999

IE9:

SCRIPT28: Out of stack space 
SCRIPT2343: Stack overflow at line: 20 

Chrome 24:

Uncaught RangeError: Maximum call stack size exceeded 

火狐18

RangeError: arguments array passed to Function.prototype.apply is too large

注意 —由于javascript的单线程性质,无限循环最终会锁定UI并永远不会引发异常。

while(1);
for(;;);

这些都不符合。

更新 -这将删除三个字符:

eval.apply(0,Array(1e7))

MDN说那eval是最短的。
彼得·泰勒

5
eval.apply(0,Array(1e6))节省了3个字符,你甚至可以去9e9无成本
ThinkChaos

1
apply是标准的ECMAScript功能。没有任何依赖于浏览器的内容。除非你是在谈论真的老的浏览器,但这不是在假想的Netscape 2一起工作apply,无论如何,因为Array类不会在Netscape 2.存在
康拉德·博罗夫斯基

1
ES6中最短的新记录:eval(...Array(9e9))
Patrick Roberts

1
可能是非标准的,从控制台抛出了Chrome。dir.apply(0,Array(1e7));
Paul J


13

Mathematica,4个字符

x=2x

$ RecursionLimit :: reclim:递归深度超过1024。>>


1
“您可能无法定义调用自身的函数”
Tomas

13
那不是一个函数,而是一个变量(除非它根本不是看起来的样子)。
AMK 2014年

你接受了我的想法。
PyRulez 2014年

12

Clojure,12个字符

(#(%%)#(%%))

在repl中运行:

user=> (#(%%)#(%%))
StackOverflowError   user/eval404/fn--407 (NO_SOURCE_FILE:1)

这让我想起了lambda演算表达式(\x.xx)(\x.xx),但是我不太了解clojure来确定这是否正在发生。我也看不出为什么前面提到的表达式会导致堆栈溢出,所以也许您在使用Y-combinator做一些骗术?这个答案让我很感兴趣,一个解释会很好。
Zwei

12

Java-113个字符

我认为这符合“禁止自我调用方法”规则的精神。它没有明确地执行此操作,甚至通过Java语言构造完成。

public class S {
    public String toString() {
        return ""+this;
    }
    public static void main(String[] a) {
        new S().toString();
    }
}

精简版:

public class S{public String toString(){return ""+this;}public static void main(String[] a){new S().toString();}}

9
好吧,""+this实际上是""+this.toString(),因此该方法会自行调用。
True Soft

1
@TrueSoft可以肯定的是Java在StringBuilder那里抛出了一个对象。toString可能会从那里被调用。
Cruncher 2014年

1
到编译器和优化器完成时,该toString()方法最终成为public java.lang.String toString() { return this.toString(); }
Jonathan Callen

12

C,19字节

main(){int i[~0u];}

4
@Thomas是的,这在堆栈上分配了局部变量的任何计算机上的堆栈溢出。由于C语言没有堆栈溢出指示的概念(这是所有未定义的行为;其中之一表现为段错误),因此确实符合原始要求。
詹斯2014年

好的,抱歉,接受了。
Tomas

3
main.c:1:16: error: size of array 'i' is negative为我提供了gcc 4.8.1。未签名的版本main(){int i[~0U];}有效。
Csq 2014年

手动配置4GB堆栈后对我不起作用。
FUZxxl 2015年

@FUZxxl有趣;您的整数是32位吗?如果是这样,sizeof(i)则为16GB。使用ulull后缀有区别吗?某些系统过量使用内存,并且只有在写入内存后才会崩溃。
詹斯

10

GolfScript(8个字符)

{]}333*`

结果:

$ golfscript.rb overflow.gs 
golfscript.rb:246:in `initialize': stack level too deep (SystemStackError)
from /home/pjt33/bin/golfscript.rb:130:in `new'
from /home/pjt33/bin/golfscript.rb:130:in `ginspect'
from /home/pjt33/bin/golfscript.rb:130:in `ginspect'
from /home/pjt33/bin/golfscript.rb:130:in `map'
from /home/pjt33/bin/golfscript.rb:130:in `ginspect'
from /home/pjt33/bin/golfscript.rb:130:in `ginspect'
from /home/pjt33/bin/golfscript.rb:130:in `map'
from /home/pjt33/bin/golfscript.rb:130:in `ginspect'
 ... 993 levels...
from (eval):4
from /home/pjt33/bin/golfscript.rb:293:in `call'
from /home/pjt33/bin/golfscript.rb:293:in `go'
from /home/pjt33/bin/golfscript.rb:485

基本上,这会创建一个高度嵌套的数据结构,然后在尝试将其转换为字符串时溢出堆栈。


对我来说,这不会引发错误,但是会输出[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ [[[[[[[[[[[[[""]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ]]]]]]]]]]]]]]]]] (and so on, output too long for comments)
ProgramFOX 2014年

@ProgramFOX,您可以替换一些值,333它将中断。333对于我来说,这是最小的值,但是,如果您使用的是其他版本的Ruby(就我所知,也许是同一版本,也可能是其他操作系统上的同一版本),那么它在溢出之前可能会处理不同数量的堆栈帧。
彼得·泰勒

1
我的机器上的3192中断,因此6.?仍然可以正常运行而无需添加字符。
丹尼斯

10

x86汇编,NASM语法,7个字节

db"Pëý"

“Pëý”是十六进制的50 EB FD,并且

_loop:
push eax
jmp _loop

在x86汇编中。


8

红宝石,12岁

eval"[]"*9e3

SystemStackError: stack level too deep

大概与系统有关,但是您可以通过增加最后一位来增加数量级(不建议)。

编辑以进行解释:与其他一些示例类似,这将创建一个[][][]...重复9000次的字符串,然后对其进行求值:最右边的字符串[]被解析为对其余部分的函数调用,依此类推。如果它真的开始,它将抛出ArgumentError,因为它[]是一个带有[]需要一个参数的方法的对象,但是我的机器在堆栈超过九千之前抛出了一个错误。


嗯...坠毁IRB:P
门把手

哪个版本?ruby1.9.2引发“ ArgumentError:参数数量错误(1..2为0)”。
manatwork 2013年

发现了一个旧的ruby1.8.7。此处发布的代码按说明工作。
manatwork 2013年

奇怪的是,它适用于我的1.8.7、1.9.2和1.9.3。
历史学家

我会说def f;f;end;f
EMBLEM 2015年

8

Rebol(11个字符)

do s:[do s]

产量:

>> do(s:[do s])    
** Internal error: stack overflow
** Where: do do do do do do do do do do do do do do do do 
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do 
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do do do do do do do do
do do do do do do do do do do do do...

尽管Rebol具有功能,闭包和对象……但这并未定义任何功能。它定义了一个数据结构,在使用“按数据编码”范例中,可以使用DO将其视为代码。

我们可以使用REPL来探讨“什么是S”的问题:

>> s: [do s]
== [do s]

>> type? s
== block!

>> length? s
== 2

>> type? first s
== word!

>> type? second s
== word!

不要将其转换为函数,它会在结构上的当前环境中调用评估程序。


1
+1 ...我没有注意到我的答案正在定义一个函数并且违反了规则,但是编辑了我的答案以使用DO ...然后注意到您已经提交了该答案。所以我只是删除了我的,但是由于我写了为什么这没有定义对象/函数/闭包,所以我想把解释放到您的那里。我也认为做做做事很有趣,值得一试。:-)希望没事!
Rebmu博士2014年

7

C,35个字符

main(){for(;;)*(int*)alloca(1)=0;}

为什么要在分配的空间中存放任何东西?
彼得·泰勒

1
在这种情况下,这是不可能的C.解决这个问题
FUZxxl

3
@dmckee,并非所有分段错误都是堆栈溢出,但我要说的是,这是因为超出堆栈容量。
ugoren 2013年

1
@ dmckee,alloca从堆栈分配。
ugoren 2013年

1
@PeterTaylor:可能取决于实现,但就我而言alloca(1),基本上已翻译成sub $1, %esp这样,因此不会触及堆栈。
Job

7

普通Lisp,7个字符

#1='#1#

美丽...我正打算将其#1=(#1#)用于终端机和(print #1=(#1#)),但您的解决方案要好得多。
protist

实际上,只有在您尝试打印时,它才不会在读取时溢出。因此,除了1个字符的差异之外,您的情况再好不过了。
protist

您是对的,只需将其删除即可。我不确定是否有办法在读取时导致溢出。
Erik Haliewicz 2014年

实际上,#。#1 ='#1#导致读取时溢出:-)
Erik Haliewicz

7

Python-11个字符

exec'('*999

>>> exec'('*999
s_push: parser stack overflow
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError

非常聪明的解决方案。
mbomb007

7

卡西欧计算器,11次按键

在这种“语言”中很难计算字节数/令牌数-我已经给出了所需的按键次数,但不包括Shift,Alpha(第二个Shift键),=最后还有-每次按键当然适合1字节。

fx-85GT PLUS模型上进行了测试,该模型是标准的,非图形化的“非可编程”科学计算器。其他型号也可以使用。

只需堆叠11个立方根:

3√ 3√ 3√ 3√
3√ 3√ 3√ 3√
3√ 3√ 3√

它甚至没有给出关于平方根下缺少数字的语法错误。

这似乎不适用于平方根。

或者,重复cos(31次。

输出量

Stack ERROR

[AC]  :Cancel
[<][>]:Goto

我相信这可以视为堆栈溢出。堆栈似乎很小...


我一直认为这是所谓的堆栈错误,因为您“堆积”了太多根源:P
FlipTack

如果佳能计算器重复执行25次以上,则几乎任何运算符都会产生堆栈错误(至少不包括+,-,*和/)。例如,这会导致堆栈错误(没有语法错误):(((((((((((((((((((((((((
Steadybox,2013年

7

FORTH,13个字节

BEGIN 1 AGAIN

溢出值堆栈


: X X ; X(9)必须溢出返回堆栈
AMK

将不起作用(在定义呼叫时未定义X,这是自引用/递归
棘手怪胎

@ratchetfreak,这些控制字只能在编译状态下使用,因此需要将它们包装在:... ;字定义中。至少要添加6个字符,再加上至少2个字符才能作为程序执行。您也许可以缩短时间,但这是一个示例:: F BEGIN 1 AGAIN ; F。我之所以建议这样做,是因为该问题询问:“编写程序”。无论如何,无论字符数如何,您都可以为Forth投票!:-)
Darren Stone

6

后记7

{1}loop

例如。

$ gsnd
GPL Ghostscript 9.06 (2012-08-08)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>{1}loop
Error: /stackoverflow in 1
Operand stack:
   --nostringval--
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   %loop_continue   --nostringval--   --nostringval--   false   1   %stopped_push   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   %loop_continue
Dictionary stack:
   --dict:1168/1684(ro)(G)--   --dict:0/20(G)--   --dict:77/200(L)--
Current allocation mode is local
Last OS error: No such file or directory
Current file position is 8
GS<1>


6

LaTeX:8个字符

\end\end

这是此答案中使用的相同代码。本质上,\end宏会反复扩展自身,从而导致堆栈溢出:TeX capacity exceeded, sorry [input stack size=5000]。在这里可以找到更详细的解释。


5

PHP 5.4,33个字符

for($n=1e5;$n--;)$a=(object)[$a];

当嵌套的stdClass对象被自动销毁时,这会导致堆栈溢出:

$ gdb -q php
Reading symbols from /usr/bin/php...(no debugging symbols found)...done.
(gdb) set pagination 0
(gdb) r -nr 'for($n=1e5;$n--;)$a=(object)[$a];'
Starting program: /usr/bin/php -nr 'for($n=1e5;$n--;)$a=(object)[$a];'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00000000006debce in zend_objects_store_del_ref_by_handle_ex ()
(gdb) bt
#0  0x00000000006debce in zend_objects_store_del_ref_by_handle_ex ()
#1  0x00000000006dee73 in zend_objects_store_del_ref ()
#2  0x00000000006a91ca in _zval_ptr_dtor ()
#3  0x00000000006c5f78 in zend_hash_destroy ()
#4  0x00000000006d909c in zend_object_std_dtor ()
#5  0x00000000006d9129 in zend_objects_free_object_storage ()
#6  0x00000000006dee53 in zend_objects_store_del_ref_by_handle_ex ()
#7  0x00000000006dee73 in zend_objects_store_del_ref ()
#8  0x00000000006a91ca in _zval_ptr_dtor ()
#9  0x00000000006c5f78 in zend_hash_destroy ()
#10 0x00000000006d909c in zend_object_std_dtor ()
#11 0x00000000006d9129 in zend_objects_free_object_storage ()
[...]
#125694 0x00000000006dee53 in zend_objects_store_del_ref_by_handle_ex ()
#125695 0x00000000006dee73 in zend_objects_store_del_ref ()
#125696 0x00000000006a91ca in _zval_ptr_dtor ()
#125697 0x00000000006c5f78 in zend_hash_destroy ()
#125698 0x00000000006d909c in zend_object_std_dtor ()
#125699 0x00000000006d9129 in zend_objects_free_object_storage ()
#125700 0x00000000006dee53 in zend_objects_store_del_ref_by_handle_ex ()
#125701 0x00000000006dee73 in zend_objects_store_del_ref ()
#125702 0x00000000006a91ca in _zval_ptr_dtor ()
#125703 0x00000000006c4945 in ?? ()
#125704 0x00000000006c6481 in zend_hash_reverse_apply ()
#125705 0x00000000006a94e1 in ?? ()
#125706 0x00000000006b80e7 in ?? ()
#125707 0x0000000000657ae5 in php_request_shutdown ()
#125708 0x0000000000761a18 in ?? ()
#125709 0x000000000042c420 in ?? ()
#125710 0x00007ffff5b6976d in __libc_start_main (main=0x42bf50, argc=3, ubp_av=0x7fffffffe738, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe728) at libc-start.c:226
#125711 0x000000000042c4b5 in _start ()

2
+1是PHP在CodeGolf上的第二次亮相!
Bojangles 2013年

5

Q / k(16个字符)

不知道这是否符合挑战精神,但我不认为这违反了规则:

s:{f`};f:{s`};f`

可惜C#需要这么多的输入,您启发了我的答案!
安德鲁·格雷

5

一堆相同的样式:

Python,30岁

(lambda x:x(x))(lambda y:y(y))

Javascript,38

(function(x){x(x)})(function(y){y(y)})

卢阿(44岁)

(function(x) x(x) end)(function(y) y(y) end)

在Python x=lambda y:y(y);x(x)中较短(20个字符)。此函数不是递归的。x调用作为参数传递给它的任何函数。
AMK

红宝石2.0 -->x{x[x]}[->y{y[y]}]
约翰·德沃夏克

Mathematica#@#&[#@#&]
alephalpha

您只是在使用递归,然后为什么不这样做(例如在JS中:(function x(){x()})()?
xem 2014年

@xem要求说没有递归,这就是为什么。
丹尼

5

C#:106 86 58 46 32 28

32:吸气剂可以使您的机器在C#中变得容易:

public int a{get{return a;}}

1
无需二传手public int a {get{return a;}}
Mike Koder

3
这违反了“不允许您定义调用自身的函数”的规则。诚然,它隐藏在语法糖的后面,但仍然缺少挑战的要点。
彼得·泰勒

添加设置器在某种程度上规避了该规则,因为现在您有两个互相调用的函数。但是我想知道:这是否仍然违反了OP在此挑战背后的意图?
安德鲁·格雷

1
据我了解,该想法是在语言的解释器或标准API中找到一些嵌套过多的递归。在C#中,这可能不太容易。
彼得·泰勒

1
为什么是“公共字符串”?“ int”也一样有效:int a { get { return a; } }
NPSF3000

5

INTERCAL,12个字节

(1)DO(1)NEXT

说明:

NEXT是INTERCAL的子程序调用版本(或者至少是您可以得到的最接近的版本)。它将当前位置推入NEXT堆栈并跳转到给定标签。

但是,如果NEXT堆栈长度超过80,您将获得堆栈溢出的INTERCAL版本:

ICL123I PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON
    ON THE WAY TO 1
        CORRECT SOURCE AND RESUBNIT

在Ideone上尝试。


6
“消失在黑礁湖中了”,这是什么,ArnoldC?
Addison Crump

5

莫宁新月,139 133

Take Northern Line to Bank
Take Circle Line to Temple
Take Circle Line to Temple
Take Circle Line to Bank
Take Northern Line to Angel

4

X86汇编(AT&T),33个字符

请注意,尽管我将标签main用作跳转目标,但这不是递归函数。

.globl main
main:push $0;jmp main

好主意:这是一种没有递归的递归!
Andrea Corbellini 2013年

使用a86:dd 0fdeb6010个字符!
Skizz 2013年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.