HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
0413
Synthスタック領域のオーバーフローです6未解決


Synth

リンク

2008/4/13(Sun) 13:05:51|NO.15070

スタック領域のバッファオーバーフローです、と怒られる時は

*a await 1 gosub *b *b await 1 goto *a
など、subとtoの使い分けができていない場合に言われるのですか?

書き方を修正すればどのようなプログラムでも
スタック領域のオーバーフローエラーと怒られることはなくなりますか?

1000行を超え、長くプログラムを走らせてるとよく言われ
ソースを破棄する毎日なので質問させて頂きますorz



この記事に返信する


uhouho

リンク

2008/4/13(Sun) 14:07:04|NO.15071

詳しいことは解りませんが、
「スタック領域のバッファオーバーフロー HSP」でググってみたら出てきました。
http://quasiquote.org/hspwiki/HSP3%e3%81%aeFAQ%3a%e3%82%a8%e3%83%a9%e3%83%bc%e3%83%a1%e3%83%83%e3%82%bb%e3%83%bc%e3%82%b8%e3%81%ae%e6%84%8f%e5%91%b3%e3%81%a8%e5%af%be%e5%87%a6%e6%b3%95%e3%81%8c%e5%88%86%e3%81%8b%e3%82%89%e3%81%aa%e3%81%84#H-f866mg

29 "スタック領域のオーバーフローです"

サブルーチン呼び出しや、式の評価の処理中にスタックが破壊された場合に表示されます。通常、表示されることはありません。 これが表示される場合は、システムに致命的なエラーが発生したことを示しています。

原因

サブルーチンのネストが多く呼び出しが連続したとき、HSPがサブルーチンの呼び出し元を覚えきれないときエラーになります。
対処

1. スクリプトの構造を見直して「gosub => return => gosub => return」という流れになるようにしましょう。
2. スタックを自己管理してHSPのエラーが出ないようにする。



uhouho

リンク

2008/4/13(Sun) 14:33:26|NO.15072

> 書き方を修正すればどのようなプログラムでも
> スタック領域のオーバーフローエラーと怒られることはなくなりますか?
sublev(ネスト)が128を超える再帰処理は、普通には出来ないのでしょうか?

実験:

#module ;Genkaiを変えて実験 ;#const Genkai 126;Case1:正常終了 ;#const Genkai 127;Case2:正常終了、しかし終了後にエラー(何故?) #const Genkai 128;Case3:"スタック領域のオーバーフローです"のエラー #deffunc test pos sublev\20*30,sublev/20*30 mes ""+sublev wait 1 if sublev<Genkai:test return #global test pos 0,300 mes "正常終了" stop
個人的には、Case2の結果の理由が気になります…(汗



As

リンク

2008/4/13(Sun) 15:13:31|NO.15075

gosub でジャンプした場合、 処理過程の中で必ず return しなければなりません。


gotoを使いたい場合は、returnしてから使用するか、gotoでジャンプしたラベル先で
return する必要があります。gosubの数だけreturnがあるものです。


*a gosub *b mes "ラベルAまで戻ってきました" stop *b goto *c *c //ラベルbからgotoで移動された return //ラベルaに戻る



Synth

リンク

2008/4/13(Sun) 21:54:47|NO.15087

皆さん、書き込みありがとうございます。
質問する前に1度はググるべきだったと今反省してます。。。以後気をつけますorz

uhouhoさん
>式の評価の処理中にスタックが破壊された
dim test,3
test.0=0:test.1=10:test.2=20 kari=2 mes test.(kari-1)//test.1が表示される(2-1は1) stop
“このような書き方をするのはよくない”とお聞きしたのですが事実なのですか?
また、これはスタックエラーとは関係ありますか?

>1. スクリプトの構造を見直して「gosub => return => gosub => return」という流れになるようにしましょう。
頑張ります;
>2. スタックを自己管理してHSPのエラーが出ないようにする。
スタックの自己管理というのが気になります。詳しく教えて貰えますか?

Asさん
>gosub でジャンプした場合、 処理過程の中で必ず return しなければなりません。
gosubで呼び出すラベルには先頭に『sb_』を記述するなど
気をつけて書いているつもりなのですが、
エラーが出ている以上、gosub/gotoの使い分けが出来ていないようですorz

returnを行えれば、gosub中でもgotoを使用出来るみたいですね。
ありがとうございますー



FUJI

リンク

2008/4/14(Mon) 21:30:43|NO.15106

* 式の入れ子によるスタックオーバーフローについて
http://d.hatena.ne.jp/chaperatta/20080226/1204004533 の記事を書いた者です。
式の入れ子、といっても 「 0+0+0+0+0 」 を 「 (((0+0)+0)+0)+0 」 のように変形してもコンパイル後のコードは変わりませんし、スタックの消費量も変わりません。

内部的な話になるのですが、HSPのパラメータ式はコンパイル後のコードでは逆ポーランド記法に変換されます。「 (((0+0)+0)+0)+0 」 という式は 「 0 0 + 0 + 0 + 0 + 」 となってスタックも 2 つしか消費しません。反対に 「 0+(0+(0+(0+0))) 」 という式は 「 0 0 0 0 0 + + + + 」 となってスタックも 0 の数だけ消費しちゃいます。

で test.(kari-1) も test(kari-1) とコンパイル結果は同じなのでその点で問題はないはずです。“このような書き方をするのはよくない”というのはそのスクリプトのどこについていっているのかよく分かりませんけど。

* NO.15072 実験プログラム Case 2 での異常終了について
Case 2 で異常終了するのはバグです。 OpenHSP で修正をコミットしています ;)
<http://dev.onionsoft.net/trac/changeset/65>

* スタックの自己管理について
おそらく再帰のコードをスタックと goto に変換することで回避せよということではないかと思います。

また、開発wikiに gosub を自前スタックとgotoで置き換えるという大変邪悪な(笑)コードがありましたので紹介します。
http://hspdev-wiki.net/?%A5%B7%A5%B9%A5%C6%A5%E0%A4%CE%A5%B9%A5%BF%A5%C3%A5%AF%A4%F2%BB%C8%A4%EF%A4%CA%A4%A4gosub



uhouho

リンク

2008/4/14(Mon) 22:23:47|NO.15107

FUJIさん、解説ありがとうございます!
すごく助かりました(^^;
> 式の入れ子、といっても 「 0+0+0+0+0 」 を 「 (((0+0)+0)+0)+0 」 のように変形してもコンパイル後のコードは変わりませんし、スタックの消費量も変わりません。
やっぱり間違っていましたかw
その上勝手に記事を引用してしまい、申し訳ございません(汗

内部に関してはまだ詳しく知らないので…自分も勉強させて頂きますm(_ _)m
(自分の書いた間違った情報を書いた記事(FUJIさんの前にありました)は消させて頂きました。)



ONION software Copyright 1997-2023(c) All rights reserved.