[topic] スタックの操作

多くの手続き型言語では、スタックサイズが決められています。
再帰などで画像処理などを行うと、しばしばスタックオーバーフローが発生します。
そこで、スタックオーバーフローが可能な言語において、特定の環境、特定の言語のデフォルト設定で、

1.スタックオーバーフローを発生させるコードを書きなさい
2.スタックオーバーフロー時のスタックの大きさを求めなさい
3.組み込み型変数(int,double,List,Dictionary,etc...)のスタック消費サイズを求めなさい
4.スタックサイズを変更する方法を書きなさい

何を以ってデフォルトとするかは非常に怪しいですが、そこらへんは適当にお願いします。

3はネイティブコードを吐く言語であれば、たぶんそのままですが、
スクリプト言語であれば、見える大きさと実メモリ上の大きさが異なるので、その場合はよろしくお願いします。
また組み込み型が多数ありすぎる言語の場合、よく使われるものを適当に示してください。

4は開発環境の設定や、ビルドオプションなど、コードの外からの指定になる場合がある思うので、
そのような場合は、その旨を明記してください。

#自分がPythonで画像処理プログラムを書いていたら、スタックオーバーフローさせてしまったので投稿してみる
#200*200の画像でオーバーフローするなよ。デフォ設定が小さすぎる・・・
ちなみにpythonでは関数呼び出しの回数に制限があり、
それがデフォで1000回になっているようです。

例の画像処理は呼び出し限界を画像のピクセル数にして解決

Posted feedbacks - Nested

Flatten Hidden
1と4だけですが投稿します。ただし Thread クラスのコンストラクタでスタックサイズを指定するオーバーロードは使用が推奨されてません。 ……2と3はどう書けば良いんだろう。.NET Framework 2.0 以降は、StackOverflowException は catch できず、オーバーフロー時点でランタイムが停止してしまいます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
using System;
static class Program {
    static void Main() {
        new System.Threading.Thread(Test, 1024 * 1024).Start();
    }
    static long cnt = 0;
    static void Test() {
        Console.WriteLine(cnt++);
        Test();
    }
}

本当のスタックオーバーフローではありませんが、すぐ書ける Emacs Lisp の場合でも。

関数呼び出しのネスト数が max-lisp-eval-depth の値を超えるとエラーになります。初期値は 300 ぐらいが普通みたいです。

普通の変数なので setq で大きい数に設定すれば増やせますが、documentation に「大きくしすぎるとクラッシュするかも」とか書いてあります。

1
2
(defun f () (f))
(f) ;; => Debugger entered--Lisp error: (error "Lisp nesting exceeds `max-lisp-eval-depth'")
1だけです。callなしで%0だけにすると無限ループになるみたいです。

>stacktest

>call stacktest

 ...

>call stacktest

>call stacktest
******  B A T C H   R E C U R S I O N  exceeds STACK limits ******
Recursion Count=1240, Stack Usage=90 percent
******       B A T C H   PROCESSING IS   A B O R T E D      ******
1
call %0

1 (と2) だけです。スタックサイズは処理系に依存し、オーバーフローするかどうかも処理系依存です。このコードでは Rhino のインタプリタモード (-opt -1) でオーバーフローしません)。

二回にわけているのは、処理系によっては try/catch でスタックオーバーフローがキャッチできないからです。

Safari 3: 500
Opera 9.24: 3341
Firefox 3 beta2: 261503
1
2
javascript:n=0;(function(){n++;arguments.callee()})();
javascript:alert(n);

Index

Feed

Other

Link

Pathtraq

loading...