C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C# MVC でのスタックオーバーフロー /はな (17/09/06(Wed) 15:56) #85038
Re[1]: C# MVC でのスタックオーバーフロー /WebSurfer (17/09/06(Wed) 16:43) #85040
  └ Re[2]: C# MVC でのスタックオーバーフロー /はな (17/09/06(Wed) 17:22) #85041
    ├ Re[3]: C# MVC でのスタックオーバーフロー /ぶなっぷ (17/09/06(Wed) 18:25) #85042
    └ Re[3]: C# MVC でのスタックオーバーフロー /WebSurfer (17/09/06(Wed) 19:21) #85043
      └ Re[4]: C# MVC でのスタックオーバーフロー /はな (17/09/07(Thu) 11:02) #85048 解決済み
        └ Re[5]: C# MVC でのスタックオーバーフロー /なちゃ (17/09/07(Thu) 12:00) #85049 解決済み
          └ Re[6]: C# MVC でのスタックオーバーフロー /なちゃ (17/09/07(Thu) 12:04) #85050 解決済み
            └ Re[7]: C# MVC でのスタックオーバーフロー /はな (17/09/07(Thu) 15:39) #85052
              ├ Re[8]: C# MVC でのスタックオーバーフロー /ぶなっぷ (17/09/07(Thu) 15:49) #85053
              └ Re[8]: C# MVC でのスタックオーバーフロー /魔界の仮面弁士 (17/09/07(Thu) 16:27) #85054
                └ Re[9]: C# MVC でのスタックオーバーフロー /はな (17/09/07(Thu) 17:23) #85055
                  ├ Re[10]: C# MVC でのスタックオーバーフロー /魔界の仮面弁士 (17/09/07(Thu) 18:18) #85057
                  └ Re[10]: C# MVC でのスタックオーバーフロー /WebSurfer (17/09/07(Thu) 18:09) #85056
                    └ Re[11]: C# MVC でのスタックオーバーフロー /はな (17/09/11(Mon) 12:45) #85095
                      └ Re[12]: C# MVC でのスタックオーバーフロー /とっちゃん (17/09/11(Mon) 17:07) #85106
                        ├ Re[13]: C# MVC でのスタックオーバーフロー /はな (17/09/11(Mon) 21:14) #85111
                        │└ Re[14]: C# MVC でのスタックオーバーフロー /Azulean (17/09/11(Mon) 21:37) #85112
                        │  └ Re[15]: C# MVC でのスタックオーバーフロー /とっちゃん (17/09/12(Tue) 11:31) #85127
                        └ Re[13]: C# MVC でのスタックオーバーフロー /Jitta (17/09/12(Tue) 22:20) #85140
                          └ Re[14]: C# MVC でのスタックオーバーフロー /はな (17/09/13(Wed) 11:20) #85143
                            ├ Re[15]: C# MVC でのスタックオーバーフロー /とっちゃん (17/09/13(Wed) 13:18) #85145
                            │└ Re[16]: C# MVC でのスタックオーバーフロー /はな (17/09/13(Wed) 15:24) #85146
                            └ Re[15]: C# MVC でのスタックオーバーフロー /とっちゃん (17/09/13(Wed) 16:29) #85147


親記事 / ▼[ 85040 ]
■85038 / 親階層)  C# MVC でのスタックオーバーフロー
□投稿者/ はな (1回)-(2017/09/06(Wed) 15:56:52)

分類:[C#] 

C# MVCから参照するDLLでスタックオーバーフローが発生して困っています。

参照するDLLは二つあり、片方はスタックオーバーフローせず、片方はスタックオーバーフローします。
xxx.dll・・・オーバーフローしてしまう。スタック回数は1000回程度だが、300ほどでオーバーフロー。
yyy.dll・・・オーバーフローしない。スタック回数10000回以上

この二つのDLLをコンソールアプリケーションから参照した場合にはどちらもスタックオーバーフローしません。

xxx.dllとyyy.dllでなにが違うのか?どこを調べるべきか?
MVCとコンソールアプリケーションで何が違うのか?どこを調べるべきか?

よろしくお願いいたします。
[ □ Tree ] 返信 編集キー/

▲[ 85038 ] / ▼[ 85041 ]
■85040 / 1階層)  Re[1]: C# MVC でのスタックオーバーフロー
□投稿者/ WebSurfer (1298回)-(2017/09/06(Wed) 16:43:07)
No85038 (はな さん) に返信
> C# MVCから参照するDLLでスタックオーバーフローが発生して困っています。

何を作っているのですか? ASP.NET MVC アプリ?

あと、開発環境・運用環境が不明です。

他にも不明点が多々ありますが、それら 2 つは質問するときに最低限書くべきことなのですが・・・


[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85040 ] / ▼[ 85042 ] ▼[ 85043 ]
■85041 / 2階層)  Re[2]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (3回)-(2017/09/06(Wed) 17:22:58)
これは失礼しました。

開発環境はVisualStudio 2013です。
運用・・・とうか今はデバッグ実行で確認しています。

IISに乗せてもスタックオーバーフローは解決しません。
.NET Framework 4.0です。

ASP.NET MVC で作成しています。


コンソールアプリケーションはDLLの動作確認用にテスト的に作成したものです。



No85040 (WebSurfer さん) に返信
> ■No85038 (はな さん) に返信
>>C# MVCから参照するDLLでスタックオーバーフローが発生して困っています。
>
> 何を作っているのですか? ASP.NET MVC アプリ?
>
> あと、開発環境・運用環境が不明です。
>
> 他にも不明点が多々ありますが、それら 2 つは質問するときに最低限書くべきことなのですが・・・
>
>
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85041 ] / 返信無し
■85042 / 3階層)  Re[3]: C# MVC でのスタックオーバーフロー
□投稿者/ ぶなっぷ (124回)-(2017/09/06(Wed) 18:25:21)
スタックオーバーフローは私の経験上、ほとんどの場合が、
・巨大配列のnew
・深すぎる(または無限)再帰呼び出し
でした。

前者はコレクション使ってれば起きないはずなんで、
一般的なコードなら後者でしょう。

 1) 再帰呼び出しの抜け口がなくなってしまうパターンがないか?
 2) ツリーなどを再帰呼び出しで操作していて、ツリーが深すぎないか?

私の場合、過去に2)ではまって、
再帰コードを非再帰コードに書き換えたことがあります。

理論的に、再帰コードは非再帰コードに書き換えられることが保証されています。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85041 ] / ▼[ 85048 ]
■85043 / 3階層)  Re[3]: C# MVC でのスタックオーバーフロー
□投稿者/ WebSurfer (1299回)-(2017/09/06(Wed) 19:21:00)
No85041 (はな さん) に返信

私のレスを全文引用してますが、引用は必要最小限にとどめてください。見難くなります。

> 参照するDLLは二つあり、片方はスタックオーバーフローせず、片方はスタックオーバーフローします。
> xxx.dll・・・オーバーフローしてしまう。スタック回数は1000回程度だが、300ほどでオーバーフロー。
> yyy.dll・・・オーバーフローしない。スタック回数10000回以上

スタックオーバーフローとなるのはどのように確認したのでしょう?(失礼ながら、ホントに
スタックオーバーフルーなのかちょっと疑ってます)

「スタック回数」というのは何なのですか? メソッドの再帰呼び出しの深さのようなもので
深くなるほど(回数に比例して)スタックメモリの消費量が増えるのですか?

エラーが実際にスタックオーバーフローで、「スタック回数」に比例してスタック消費量が増え
るということであれば、自分が想像できるのは、

> この二つのDLLをコンソールアプリケーションから参照した場合にはどちらもスタックオーバーフローしません。

ASP.NET Web アプリとコンソールアプリでは使用できるスタックのサイズが違うからだと思いま
す。それ以外に違いが出る原因は自分は思いつきません。

前者は 256KB という記事を見つけました。

Stack sizes in IIS – affects ASP.NET
https://blogs.msdn.microsoft.com/tom/2008/03/31/stack-sizes-in-iis-affects-asp-net/

後者は 1 MB だと思います。

Thread Stack Size
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686774(v=vs.85).aspx

> xxx.dllとyyy.dllでなにが違うのか?どこを調べるべきか?

「スタック回数」の 1 回あたりのスタック消費量が違う(xxx.dll > yyy.dll)からではないかと
思います。そこを調べてみては?

以上は自分の想像です。これ以上のことは、今提供されている情報ではわかりません。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85043 ] / ▼[ 85049 ]
■85048 / 4階層)  Re[4]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (4回)-(2017/09/07(Thu) 11:02:04)
ぶなっぷさん、WebSurferさん貴重な情報ありがとうございます。

> スタックオーバーフローは私の経験上、ほとんどの場合が、
> ・巨大配列のnew
> ・深すぎる(または無限)再帰呼び出し
> でした。

巨大な2次元配列使ってます。

スタック領域の不足ではなく、連続したメモリ領域の確保ができない可能性があるということですね。
スタックオーバーフローエクセプションが出ていたので、スタック領域のことばかり考えていました。

お二方の情報を元に改修を考えて見ます。

解決済み
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85048 ] / ▼[ 85050 ]
■85049 / 5階層)  Re[5]: C# MVC でのスタックオーバーフロー
□投稿者/ なちゃ (218回)-(2017/09/07(Thu) 12:00:50)
巨大配列のnewでStackOverflowってあり得ますかね…?

同じコードで環境によるというのは、すでに出されてるとおりASP.NET環境のスタックサイズの違いによる影響の可能が高そうな気はしますが、
開発サーバやIIS Expressでも同様なのかはちょっと分かりません。

あとは普通にライブラリで再起やスタックサイズの消費が大きいメソッドがあるかですかね。
例えばソートとか、組み込みのグリッドのソート機能でスタックオーバーするようなこともあったりしますので、
必ずしも自コード上で明らかに再起などがあるとは限りません。

解決済み
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85049 ] / ▼[ 85052 ]
■85050 / 6階層)  Re[6]: C# MVC でのスタックオーバーフロー
□投稿者/ なちゃ (219回)-(2017/09/07(Thu) 12:04:55)
追加です。
開発環境でのデバッグ中なら、スタックオーバーしたときの例外情報とかでスタックトレース確認できないですかね?

ていうかちょっと未だにスタック回数の意味分かってないので、何か認識違いがある予感はしますが…
解決済み
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85050 ] / ▼[ 85053 ] ▼[ 85054 ]
■85052 / 7階層)  Re[7]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (5回)-(2017/09/07(Thu) 15:39:39)
返信ありがとうございます。

スタックの深さが300程度でスタックオーバーフローするのが腑に落ちないでいたのです。

スタックトレースで、300程度の呼び出し履歴になってます。

自前で関数の呼び出し回数(深度)を数えて「200を超えたら、いったん戻る」というようにコーディングすると最後まで計算できます。

処理の概要は
A1の値が知りたいときにA1の値を計算するために必要なほかの値を先に計算してからA1を求めるようなことをしてます。
A1=B1 + C1
B1=5
C1=B2 + D2
・・・
Excelでするような計算です。(計算式はユーザが自由に変更します)

呼び出し深度の計測でC200までいってしまったら、A1の計算を保留して、C200を先に計算して・・・
という方法で回避してますが速度的に厳しいのと、スタック領域が少ないのが腑に落ちなくて質問しました。
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85052 ] / 返信無し
■85053 / 8階層)  Re[8]: C# MVC でのスタックオーバーフロー
□投稿者/ ぶなっぷ (125回)-(2017/09/07(Thu) 15:49:35)
スタックはいろんな目的で使用されます。
・ローカル変数
・メソッドのコールスタック
・メソッドの引数
・メソッドの戻り値
    :

したがって、
> 巨大な2次元配列使ってます。
が再帰呼び出しされるメソッドのローカル変数なら、
比較的少ない再帰呼び出しでもスタックオーバーフローするはずです。

といいつつ、私の知識はC++時代のものなので、
C#だとメモリ確保の方法が違ってるかもです(^^;

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85052 ] / ▼[ 85055 ]
■85054 / 8階層)  Re[8]: C# MVC でのスタックオーバーフロー
□投稿者/ 魔界の仮面弁士 (1404回)-(2017/09/07(Thu) 16:27:41)
No85052 (はな さん) に返信
> スタックの深さが300程度でスタックオーバーフローするのが腑に落ちないでいたのです。

300で落ちるのが妥当なのかは、具体的なコードを見ていないので判断できませんが、
たとえば極端な例として、下記のようなコンソールアプリを用意してみたところ、
60 回までは耐えられますが、61 回目で StackOverflowException を吐きました。

public struct ST0 { public ST1 a, b, c, d; }
public struct ST1 { public ST2 a, b, c, d; }
public struct ST2 { public ST3 a, b, c, d; }
public struct ST3 { public ST4 a, b, c, d; }
public struct ST4 { public decimal a, b, c, d; }

class Program {
 static void Main() { Loop(300, default(ST0)); }
 static void Loop(int i, ST0 z) { if (i > 0) Loop(i - 1, z); }
}


なお、コンパイル後に
 editbin /STACK:4000000 "C:\…\ConsoleApplication1.exe"
とすれば、244 回までは耐えられるようになりますし、
/STACK:8000000 にすれば、488 回まで耐えられました。
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85054 ] / ▼[ 85057 ] ▼[ 85056 ]
■85055 / 9階層)  Re[9]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (6回)-(2017/09/07(Thu) 17:23:58)
> なお、コンパイル後に
>  editbin /STACK:4000000 "C:\…\ConsoleApplication1.exe"
> とすれば、244 回までは耐えられるようになりますし、
> /STACK:8000000 にすれば、488 回まで耐えられました。

C#のスタック領域変更が見つけられなかったので助かりました。
ありがとうございます。

ローカル変数はあまり使ってません。5,6個です
クラス変数に
・巨大な2次元配列
・大量の関数ポインタを保存したDictionary
があります。
関数が5万ぐらいあります。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85055 ] / 返信無し
■85057 / 10階層)  Re[10]: C# MVC でのスタックオーバーフロー
□投稿者/ 魔界の仮面弁士 (1405回)-(2017/09/07(Thu) 18:18:23)
2017/09/07(Thu) 18:19:09 編集(投稿者)

No85055 (はな さん) に返信
>> editbin /STACK:4000000 "C:\…\ConsoleApplication1.exe"
> C#のスタック領域変更が見つけられなかったので助かりました。

No85043 で紹介された URL にも書いてありましたよね?


ちなみに現在のスタックサイズを確認する場合は、
 DUMPBIN /headers ファイル
です。先の URL でも少し触れられていますが、
OPTIONAL HEADER VALUES という見出しの下に
  100000 size of stack reserve
 1000 size of stack commit
などと表示されるので、それで確認できます。

※DUMPBIN で commit も調整する場合は /STACK:reserve,commit



Web アプリの場合、IIS の実行プロセスを無理やり DUMPBIN で調整するというのも
リスクがありそうなので、再帰的な呼び出しが起きないよう、現状のコードを
組みなおすのが現実的なところかと思います。


あとは一応、こういうものもあるようですが…
使ったことが無いので、回避策になるかは分かりません。
https://msdn.microsoft.com/ja-jp/library/5cykbwz4.aspx
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85055 ] / ▼[ 85095 ]
■85056 / 10階層)  Re[10]: C# MVC でのスタックオーバーフロー
□投稿者/ WebSurfer (1300回)-(2017/09/07(Thu) 18:09:54)
No85055 (はな さん) に返信

> C#のスタック領域変更が見つけられなかったので助かりました。
> ありがとうございます。

editbin は先のレスで紹介した記事に書いてあるのですが、見つからなかったようですね。


> ローカル変数はあまり使ってません。5,6個です
> クラス変数に
> ・巨大な2次元配列
> ・大量の関数ポインタを保存したDictionary
> があります。
> 関数が5万ぐらいあります。

そう言われても、何が問題で、どう改善するのがベストかは分かりません。少なくとも自分は。

ただ、スタックオーバーフローには間違いなさそうなので、解決策はスタックを増やすか、.dll を
書き換えてスタックの消費量を減らすかということになるはずです。

どういう手段を取るかは質問者さんが考えて決めることだと思います。(現状で、ここに書いてある
こと以外は何も知り得ない第三者が判断できることではなさそうです)
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85056 ] / ▼[ 85106 ]
■85095 / 11階層)  Re[11]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (7回)-(2017/09/11(Mon) 12:45:09)
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\editbin.exe" /STACK:1048576 C:\Windows\System32\inetsrv\w3wp.exe

LINK : fatal error LNK1104: ファイル 'w3wp.exe' を開くことができません。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85095 ] / ▼[ 85111 ] ▼[ 85140 ]
■85106 / 12階層)  Re[12]: C# MVC でのスタックオーバーフロー
□投稿者/ とっちゃん (459回)-(2017/09/11(Mon) 17:07:12)
No85095 (はな さん) に返信
> "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\editbin.exe" /STACK:1048576 C:\Windows\System32\inetsrv\w3wp.exe
>
> LINK : fatal error LNK1104: ファイル 'w3wp.exe' を開くことができません。
>

これだけだと何が言いたいのかよくわかりませんが、このエラー自体は、リンカーのエラーです。

おそらく、w3wp.exe のスタックサイズを広げれば解決するからやってみようとしたらエラーになった
ということなんだと思いますが、そもそも自分で開発しているアプリではないプログラムをむやみやたらと
書き換えていいということはありません。

特にシステムモジュールは、書き換えできないようにシステムレベルでロックダウンされるように作られているので
一時的に書き換えられたとしても、すぐに元に戻ってしまいます。


また、仮にスタックサイズを拡張できたとしても、変更されるのは開発環境だけで
運用環境が変わるわけではありません。
そのため、リリース後にスタックオーバーフローが発生して、エラーが再発することになります。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85106 ] / ▼[ 85112 ]
■85111 / 13階層)  Re[13]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (8回)-(2017/09/11(Mon) 21:14:08)
回答ありがとうございます。

IISExpressの方はこの方法でエラー回避できたので、これが一番楽だと思ったのですが、なかなか厳しいです。

この件に関して日本語の情報が少ないのも悩みです。

WFPやら、スレッドやらのやり取りがあるようなのですが、いまいち要領を得なくて・・・

もう少し試行錯誤してみます。
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85111 ] / ▼[ 85127 ]
■85112 / 14階層)  Re[14]: C# MVC でのスタックオーバーフロー
□投稿者/ Azulean (861回)-(2017/09/11(Mon) 21:37:54)
No85111 (はな さん) に返信
> もう少し試行錯誤してみます。

何を目指しているのでしょうか?
仮に、今スタックを増やすことができたとしても、そのようなスタックを浪費するコードを使い続ける限り、拡張・改良・修正も入るでしょうから、またスタックが足りなくなることが予想されます。
そして、いつかは限界を迎えます。


すでに指摘されているとおり、システムが提供する exe の改造は阻まれますし、Windows Update などで容易に置き換わりますので、考えに入れてはいけません。
スタックを浪費しないように修正することが将来性ある選択だとは思います。
(あるいは、プロセスを分けてしまい、別プロセスを走らせるという手もなくはないですが、別の悩みが出そうです)
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85112 ] / 返信無し
■85127 / 15階層)  Re[15]: C# MVC でのスタックオーバーフロー
□投稿者/ とっちゃん (460回)-(2017/09/12(Tue) 11:31:15)
No85111 (はな さん) に返信
> 回答ありがとうございます。
>
先に書いたのは回答ではありませんよ?


> IISExpressの方はこの方法でエラー回避できたので、これが一番楽だと思ったのですが、なかなか厳しいです。
>
先にも書いていますが、ご自身の開発環境でのみ解決できればいいのですか?

IISのプログラムのスタックサイズを拡張するのは回避策としては使えません。

システムファイルにはシステムが意図しない改変を自動的に修復するという仕組みが盛り込まれています。

ですので、一見成功したように見えてもすぐに戻ってしまうことになり何の意味もありません。



> もう少し試行錯誤してみます。

「スタック領域を拡張すれば解決するからスタック領域を拡張する」
という解決策は、スタック領域を自由に設定可能な自分で作成しているEXEの場合でのみ有効な解決策です。
IIS上で動くプログラムなど、ほかのプロセス内で動作するDLLの場合に用いることができる解決策ではありません。

なので、試行錯誤するのであれば、スタック消費量を減らす工夫か
再帰しないで動かす工夫を試行錯誤することをお勧めします。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85106 ] / ▼[ 85143 ]
■85140 / 13階層)  Re[13]: C# MVC でのスタックオーバーフロー
□投稿者/ Jitta (309回)-(2017/09/12(Tue) 22:20:49)

・ヒープに移す
・再帰呼び出しではなく、データ構造で同じことをする
普通、検討するのはこのあたり。
[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85140 ] / ▼[ 85145 ] ▼[ 85147 ]
■85143 / 14階層)  Re[14]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (9回)-(2017/09/13(Wed) 11:20:40)
回答ありがとうございます。

計算式が長いとスタックオーバーフローが発生してしまうのかもしれません。

double A1() {return B1() == 0 ? 0 : (C1() + func2(func1(D1(), AD5()), A2())) / B1()};
double A2() {return B2() == 0 ? 0 : (C2() + func2(func1(D2(), AD5()), A3())) / B2()};
double A3() {return B3() == 0 ? 0 : (C3() + func2(func1(D3(), AD5()), A4())) / B3()};
・・・

計算式をユーザが変更できる仕様のため、再起呼び出しをやめることができないのです。
ローカル変数にばかり気をとられていましたが、関数の戻り値を変数に代入していなくてもスタック対象なのかもしれません。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85143 ] / ▼[ 85146 ]
■85145 / 15階層)  Re[15]: C# MVC でのスタックオーバーフロー
□投稿者/ とっちゃん (461回)-(2017/09/13(Wed) 13:18:03)
No85143 (はな さん) に返信
> 回答ありがとうございます。
>
> 計算式が長いとスタックオーバーフローが発生してしまうのかもしれません。
>
> double A1() {return B1() == 0 ? 0 : (C1() + func2(func1(D1(), AD5()), A2())) / B1()};
> double A2() {return B2() == 0 ? 0 : (C2() + func2(func1(D2(), AD5()), A3())) / B2()};
> double A3() {return B3() == 0 ? 0 : (C3() + func2(func1(D3(), AD5()), A4())) / B3()};
> ・・・
>
> 計算式をユーザが変更できる仕様のため、再起呼び出しをやめることができないのです。
> ローカル変数にばかり気をとられていましたが、関数の戻り値を変数に代入していなくてもスタック対象なのかもしれません。
>

計算式なるものがどのようなものなのか、それがどういう風にプログラムに作用するのかなどはわかりませんが
現在の状況だと、どれだけスタックエリアを膨大にしてもユーザーが計算式を長くしたら(スタックをより消費するような計算式にしたら)、
スタックオーバーフローが発生してしまうのではありませんか?

外部データに依存するということは、今エラーになる外部データで対処療法的な回避を行っても
ほかのデータにしたら同じエラーが発生してしまう可能性を含んでいるということを意味します。

根本的な対策をとらない限り、エラーが出たらスタックを拡張し。。。ということを繰り返すことになります。
仮にそのような回避策が可能であったとしてもそれはスタックサイズが確保可能な上限に来た時点で破綻してしまうことになり
どこかで根本的な対応をとらない限り解決することはないのではありませんか?

再帰呼び出しをやめることができないのは再帰することを前提としたアルゴリズムだからですよね?
どのようなプログラムコードかわからないので、再帰しないアルゴリズムに変更できるものかどうかについてはわかりません。

ですが、再帰するとだめであるということがわかっている以上それ以外の解決策を模索するしかないので
再帰しない形にアルゴリズムを改める必要があると思います。

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85145 ] / 返信無し
■85146 / 16階層)  Re[16]: C# MVC でのスタックオーバーフロー
□投稿者/ はな (10回)-(2017/09/13(Wed) 15:24:58)
>>double A1() {return B1() == 0 ? 0 : (C1() + func2(func1(D1(), AD5()), A2())) / B1()};
>>double A2() {return B2() == 0 ? 0 : (C2() + func2(func1(D2(), AD5()), A3())) / B2()};
>>double A3() {return B3() == 0 ? 0 : (C3() + func2(func1(D3(), AD5()), A4())) / B3()};
>>・・・

> ですが、再帰するとだめであるということがわかっている以上それ以外の解決策を模索するしかないので
> 再帰しない形にアルゴリズムを改める必要があると思います。

C#が自動的にツリー状に関数呼び出ししている部分を自前で実装するには
1.各関数内に登場するメソッドを取得
2.呼び出しツリーを再帰を使わず作成
3.ツリーの末端から計算する
でしょうか。

関数内に登場するメソッドを取得することってできますか?
(クラスが持っているメソッドは取得できますが・・・)

[ 親 85038 / □ Tree ] 返信 編集キー/

▲[ 85143 ] / 返信無し
■85147 / 15階層)  Re[15]: C# MVC でのスタックオーバーフロー
□投稿者/ とっちゃん (462回)-(2017/09/13(Wed) 16:29:28)
No85146 (はな さん) に返信
> >>double A1() {return B1() == 0 ? 0 : (C1() + func2(func1(D1(), AD5()), A2())) / B1()};
> >>double A2() {return B2() == 0 ? 0 : (C2() + func2(func1(D2(), AD5()), A3())) / B2()};
> >>double A3() {return B3() == 0 ? 0 : (C3() + func2(func1(D3(), AD5()), A4())) / B3()};
> >>・・・
>
>>ですが、再帰するとだめであるということがわかっている以上それ以外の解決策を模索するしかないので
>>再帰しない形にアルゴリズムを改める必要があると思います。
>
> C#が自動的にツリー状に関数呼び出ししている部分を自前で実装するには
> 1.各関数内に登場するメソッドを取得
> 2.呼び出しツリーを再帰を使わず作成
> 3.ツリーの末端から計算する
> でしょうか。
>
> 関数内に登場するメソッドを取得することってできますか?
> (クラスが持っているメソッドは取得できますが・・・)
>
C#が自動的に...というのは、何らかの自動生成コードを実行時に再解釈してさらに何かするということでしょうか?

多分求めているものではないと思いますが、CodeDOM(Code Document Object Model)とかが参考情報になるかもしれないので
リンクを張っておきます(今どきということでdocs側)。

・動的なソース コードの生成とコンパイル
https://docs.microsoft.com/ja-jp/dotnet/framework/reflection-and-codedom/dynamic-source-code-generation-and-compilation

[ 親 85038 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -