什么是导致堆栈溢出的最短代码?
为了纪念Stack Overflow的公开发行,导致堆栈溢出的最短代码是什么? 欢迎任何语言。
ETA:为了清楚这个问题,看看我是一个偶然的Scheme用户:tail-call“recursion”是真正的迭代,任何可以通过体面的编译器相对简单地转换成迭代解决scheme的解决scheme将不会被算。 😛
ETA2:我现在select了一个“最佳答案”。 看到这个职位的理由。 感谢大家的贡献! 🙂
所有这些答案,没有Befunge? 我敢打赌,这是他们最短的解决scheme:
1
不开玩笑。 尝试一下: http : //www.quirkster.com/iano/js/befunge.html
编辑:我想我需要解释这一个。 1操作数将1推到Befunge的内部堆栈上,而其他任何东西都不会在语言规则下进行循环。
使用所提供的解释器,您最终将会 – 也就是说最终 – 代表Befunge堆栈的JavaScript数组变得太大而无法重新分配浏览器。 如果你有一个简单的Befunge解释器,它有一个更小的和有界的堆栈 – 就像大多数下面的语言一样 – 这个程序会更快地引起更明显的溢出。
阅读这条线,做两次 。
你也可以在C#.net中试试这个
throw new StackOverflowException();
Nemerle :
这使用StackOverflowException 导致编译器崩溃 :
def o(){[o()]}
我目前最好的(在x86程序集)是:
push eax jmp short $-1
这导致了3个字节的目标代码( 50 EB FD
)。 对于16位代码,这也是可能的:
call $
这也导致3个字节( E8 FD FF
)。
PIC18
TK给出的PIC18答案产生以下指令(二进制):
overflow PUSH 0000 0000 0000 0101 CALL overflow 1110 1100 0000 0000 0000 0000 0000 0000
但是,CALL本身会执行堆栈溢出:
CALL $ 1110 1100 0000 0000 0000 0000 0000 0000
更小,更快的PIC18
但RCALL(相对调用)仍然较小(不是全局内存,所以不需要额外的2个字节):
RCALL $ 1101 1000 0000 0000
所以在PIC18上最小的是一个指令,16位(两个字节)。 这将需要每个循环2个指令周期。 在每个指令周期4个时钟周期,你有8个时钟周期。 PIC18具有31级堆栈,因此在第32个循环之后,将以256个时钟周期溢出堆栈。 在64MHz时,你会在4微秒和2字节溢出堆栈 。
PIC16F5x(甚至更小,更快)
但是,PIC16F5x系列使用12位指令:
CALL $ 1001 0000 0000
再次,每个循环两个指令周期,每个指令4个时钟,因此每个循环8个时钟周期。
但是,PIC16F5x具有两级堆栈,所以在第三级循环中,会有24条指令溢出。 在20MHz时,会在1.2微秒和1.5字节溢出 。
英特尔4004
英特尔4004有一个8位调用子程序指令:
CALL $ 0101 0000
对于对应于ascii“P”的好奇。 使用3级堆栈需要24个时钟周期,总共32.4微秒和一个字节 。 (除非你超频你的4004 – 来吧,你知道你想要。)
这与befunge的答案一样小,但比当前解释器中运行的befunge代码要快得多。
C#:
public int Foo { get { return Foo; } }
Hoot溢出!
// v___v let rec fo = f(o);(o) // ['---'] // -"---"-
每个任务都需要正确的工具。 符合SO溢出语言,优化产生堆栈溢出:
so
TeX的:
\def~{~.}~
结果是:
! 超过TeX容量,抱歉[input堆栈大小= 5000]。 〜 - >〜 。 〜 - >〜 。 〜 - >〜 。 〜 - >〜 。 〜 - >〜 。 〜 - >〜 。 ... <*> \ def〜{〜。}〜
胶乳:
\end\end
结果是:
! 超过TeX容量,抱歉[input堆栈大小= 5000]。 \ end#1 - > \ csname end#1 \ endcsname \ @checkend {#1} \ expandafter \ endgroup \ if @ e ... <*> \ end \ end
Z-80汇编器 – 在内存位置0x0000:
rst 00
一个字节 – 0xC7 – 将当前PC推送到堆栈并跳转到地址0x0000的无限循环。
用英语:
recursion = n. See recursion.
另一个PHP示例:
<? require(__FILE__);
BASIC中的以下内容如何?
10 GOSUB 10
(我没有一个BASIC解释器,恐怕这是一个猜测)。
我爱Cody的答案堆,所以这是我在C ++中的类似贡献:
template <int i> class Overflow { typedef typename Overflow<i + 1>::type type; }; typedef Overflow<0>::type Kaboom;
不是以任何方式代码高尔夫项目,但仍然是任何元堆栈溢出! 😛
这是我的C贡献,重达18个字符:
void o(){o();o();}
这是一个很难的尾调优化! 😛
使用名为“s.bat”的窗口batch file:
call s
使用Javascript
为了修剪更多的angular色,并让自己从更多的软件商店中走出来,让我们继续:
eval(i='eval(i)');
Groovy的:
main()
$ groovy stack.groovy:
Caught: java.lang.StackOverflowError at stack.main(stack.groovy) at stack.run(stack.groovy:1) ...
请告诉我什么是“ GNU ”的缩写。
Person JeffAtwood; Person JoelSpolsky; JeffAtwood.TalkTo(JoelSpolsky);
这里希望没有尾recursion!
C – 这不是最短的,而是无recursion的。 它也不是可移植的:它在Solaris上崩溃,但是一些alloca()实现可能在这里返回错误(或者调用malloc())。 调用printf()是必要的。
#include <stdio.h> #include <alloca.h> #include <sys/resource.h> int main(int argc, char *argv[]) { struct rlimit rl = {0}; getrlimit(RLIMIT_STACK, &rl); (void) alloca(rl.rlim_cur); printf("Goodbye, world\n"); return 0; }
perl 12个字符:
$_=sub{&$_};&$_
bash在10个字符(function中的空间是重要的):
i(){ i;};i
尝试在一个汉堡上放4个以上的馅饼。 堆栈溢出。
Python :
so=lambda:so();so()
或者:
def so():so() so()
如果Python优化了尾部调用…:
o=lambda:map(o,o());o()
我在这篇文章之后select了“最佳答案”。 但首先,我要感谢一些非常独创的贡献:
- aku的。 每一个探索导致堆栈溢出一个新的和原始的方式。 做f(x)⇒f(f(x))的想法是我将在下面的下一个条目中探讨的。 🙂
- 科迪的一个给了Nemerle 编译器一个堆栈溢出。
- 和(有点勉强),GateKiller的一个关于抛出堆栈溢出exception。 😛
就像我喜欢上面的那样,挑战是做代码高尔夫球,为了公平地回答问题,我必须给最短的代码“Befunge”条目授予“最佳答案”。 我不相信有人能够打败他(虽然康拉德当然试过了),所以恭喜帕特里克!
看到大量的堆栈溢出解决scheme,我很惊讶没有人(如目前的写作)提出了Y组合(见迪克·加布里埃尔的文章, 为什么Y ,作为一个引子)。 我有一个使用Y组合器的recursion解决scheme,以及aku的f(f(x))方法。 🙂
((Y (lambda (f) (lambda (x) (f (fx))))) #f)
这是另一个有趣的计划:
((lambda(x)(xx))(lambda(x)(xx)))
Java的
Java解决scheme的稍微缩短版本。
class X{public static void main(String[]a){main(a);}}
xor esp, esp ret
3个字节:
标签: PUSHA jmp标签
更新
根据(旧?)Intel(?)文档 ,这也是3个字节:
标签: 呼叫标签