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

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

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

C# MVC でのスタックオーバーフロー [1]

[トピック内 24 記事 (21 - 24 表示)]  << 0 | 1 >>

■85143 / inTopicNo.21)  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()};
・・・

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

引用返信 編集キー/
■85145 / inTopicNo.22)  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()};
> ・・・
>
> 計算式をユーザが変更できる仕様のため、再起呼び出しをやめることができないのです。
> ローカル変数にばかり気をとられていましたが、関数の戻り値を変数に代入していなくてもスタック対象なのかもしれません。
>

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

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

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

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

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

引用返信 編集キー/
■85146 / inTopicNo.23)  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.ツリーの末端から計算する
でしょうか。

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

引用返信 編集キー/
■85147 / inTopicNo.24)  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

引用返信 編集キー/

このトピックをツリーで一括表示

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ