お世話になります。
VC++.net 2003 では一応、正常な計算結果が出ていたConsoleプログラム
が、VS2005 Standard VC++のreleaseモードでは実行時エラーが発生し、例の
『問題が発生したため、xxx.exe を終了します。
ご不便をおかけして申し訳ありません。
[エラー報告を送信する] [送信しない] 』
のダイヤログが表示されてしまいます(OSはWindows XP)。
Debugモードでは、確か、assertionが発生して(例外処理はやってません)
listのイテレータに関するエラーが出ていたのですが、いろいろオプションなど
をいじくり回しているうちに、『VCOMP.libを開くことができません』というメッ
セージが出て実行もできなくなりました(最初は確かに実行時エラーが出ていた
記憶がありましたが、よく覚えていません)。
プログラムでは
namespace buffer_space {
template <typename T> class Buffer_List {
public:
Buffer_List();
~Buffer_List();
...
private:
std::list< matrix_<T>* > lst; // バッファ配列を指すポインタを
格納
typename std::list< matrix_<T>* >::iterator p;
};
・・・
Buffer_List<value_type> buffer_list; // グローバルオブジェクトの宣言
}
のようなグローバルオブジェクトを宣言していますが、プログラムでこのオブジェクト
のメンバ関数を呼びだすと実行時エラーが発生してしまいます(使わないときは発生
しない)。
VS2005のC++コンパイラオプションから/MLが消えてマルチスレッド対応の/MT
オプションだけしかないこと、グローバルオブジェクトを使っていることがまずいの
かなとも思うのですが、VC++.net 2003 では /MLでも/MTでも一応正しい結果
が得られています。
VC++.net 2003 を使えば問題ないのですが、VS2007でも同じような症状が出ると
将来的に深刻です。何が原因なのか見当もつきません。原因に心当たりがありま
した
アサーションが出たのにコンパイラオプションでいじくり回して消したあたりが怪しそう
ですが……。
メンバ関数のどの行で発生しているか,ログを出力するなりして特定できませんか?
すみません。
最初はVS2005 + Intel C++9.1 + IntelMKL9.0の組み合わせで
実行時エラーが出てしまったので、どれが原因なのか特定できず、
計算機を変えたり、Intel C++やIntel MKLを古いバージョンに変え
たり、アンインストールしたり、環境変数を設定したりといろん
なことをやってるうちに一体何をやってしまったのか自分でも
忘れてしまいました。どこでエラーが出ているのか絞りこめたら
再度質問させていただきます。
とりあえず、VC++.net 2003 + Intel C++9.1 + Intel MKL9.0
の組み合わせではDebugモード、releaseモード共に(一応)正しい
計算結果がでるのでVS2005に原因がありそうだということはわか
りました。
あと、debugモードで動いていたとき、ワンステップづつ実行させ
ていくと、確かlistのイテレータを++pするメンバ関数でassertion
が出て、「iteratorを増加できない」という旨のメッセージが出てい
たような気がします。
1. 「Intel C++9.1 + IntelMKL9.0」がVS2005に対応していますか。
もう一度メーカに確認を取ってみたほうがいいですね。
2. .net2003の環境で動作するか?
3. 「Intel C++9.1 + IntelMKL9.0のソースがおかしいのか?」
調べてみることが必要があると思います。
補足
>「Intel C++9.1 + IntelMKL9.0のソースがおかしいのか?」
「.net2003では動作していた。」ということですから、VS2005の環境に
ソースが対応しているかどうか調べてみる必要があると思います。
# 無理にソースを変更せずに、まず「.net2003では動作していた。」と
いう段階からスタートしたほうがいいですね。
ITOさん
レスありがとうございます。
VC++.net2003 使用時には Intel C++9.1 をアドインしても問題なく実行できること
(本当に問題ないのか自信ないのですが、そう信じるしかありません)、Intel C++に
問題はないのではないか、と考えています。もう一度、Intel C++をアンインスト
ールしてVS2005で同じ症状が出るか確認する必要がありますが(よく覚えていません)。
また、Intel MKLのライブラリを一切使わない(もちろん、このときIntel MKLの関数を
プログラム中で呼び出さないようにしている)場合もやはり同じ症状が出てしまうので、
Intel MKLも関係ないのではないかと考えています。
releaseモードで下のような出力文を入れて実行してみたところ、koko1は表示され
ますが、koko2は表示されず、落ちてしまいます。スレッド関係が原因なのかなとも
思いますが、そうだとすると、かなり厄介だと思っています(技術力ないため)。
template <typename T> inline matrix_<T>* Buffer_List<T>::next_buffer()
{
std::cout<<koko1<<std::endl;
++p;
std::cout<<koko2<<std::endl;
if( p == lst.end() ) {
lst.push_back( new matrix_<T> );
--p;
}
return *p;
}
>VS2005で同じ症状が出るか確認する必要がありますが
まず確認することですね。
実際に動作させる前にメーカーに対応しているのかを確認する必要があります。
その後、可能なら実際に動かしてみるのがいいと思います。
>スレッド関係が原因なのかなとも
>思いますが、そうだとすると、かなり厄介だと思っています
>(技術力ないため)。
スレッドはVS2005で作っていますか?
もしそうならば、ソースを公開してみるのもてだと思います。
誰か解るものがいるかも知れません。
あなたが示されたコードの何処にも関数 next_buffer() に制御が移って来たときに
反復子(イテレーター)p に何が入って(何を指して)いるか分かりませんが
そこは大丈夫なんですか?
しまさん、ご指摘ありがとうございます。
グローバルクラスのコンストラクタにおいてイテレータの初期化は
行なっています。
template <typename T> Buffer_List<T>::Buffer_List()
{
reset_ptr();
}
template <typename T> inline void Buffer_List<T>::reset_ptr()
{
p = lst.begin();
chgbuff_=true;
}
ITOさんへ
マルチスレッドは使ってないですけど、C++のコンパイルオブション
スイッチがVS2005からシングルスレッド対応の/MLが消えてマルチス
レッド対応の/MTのみになったのでそれが影響しているのかなと思い
ました。ただ、VC.net 2003では/MLでも/MTでも正常な(?)結果が得ら
れているのが気になりますが。
公開したいのですがソースが2000行程度あります。また、ロジックが
かなり入り込んでいるので解説用の概念図や文書ファイルが必要です
が、まだそれを作成しておりません。ソースは行列計算用のライブラ
リですが、お見せするのが恥ずかしいものです。でもいよいよ困った
らソースをアップすることを検討してみます。
最初にreset_ptrしたタイミングで,
ちゃんとlstに要素は含まれていますか?
reset_ptrの最終行に,
assert(p != lst.end());
と入れてみてください (要#include <cassert>)。
YuOさんありがとうございます。
>reset_ptrの最終行に,
>assert(p != lst.end());
>と入れてみてください (要#include <cassert>)。
クグッって調べてみるとassertはreleaseモードでは無効とのこと、
debugモードではVCOMP.libが開けませんというエラーが出て実行
できないので
template <typename T> inline void Buffer_List<T>::reset_ptr()
{
p = lst.begin();
chgbuff_=true;
if(p == lst.end()) std::cout << p==lst.end() << std::endl;
}
とすると、一番最初に(koko1と出力する前に)
p==lst.end()が出力されてしまいました。どうやら、島さんやYuOさんが
指摘されたようにlstに要素が入ってないようです。チェックしてみます。
重要なヒントをありがとうございました。
>公開したいのですがソースが2000行程度あります。また、ロジックが
>かなり入り込んでいるので解説用の概念図や文書ファイルが必要です
すべてでなくていいです。
おさーんさんの気になる部分だけでいいです。
逆に多く公開されても解析に手間が掛かって大変です。
今でもソ-スを部分部分で公開していますが、その程度でいいと思います。
>ソースは行列計算用のライブラリです
公開しなくてもしている処理内容がわかるだけでもいいと思います。
とりあえずグローバルクラスのコンストラクタを
template <typename T> Buffer_List<T>::Buffer_List()
{
lst.push_back( new matrix_<T> );
reset_ptr();
}
とすると、実行時エラーがなくなりました。
みなさん、ありがとうございました。リストが空であっても
begin()とend()は一致しないと思い込んでました。
また、 VC++ .net 2003 では一度も実行時エラーが出ず、結果
も正しかったのでまんまと騙されてしまいました。
よほど幸運だったのかもしれませんが、こんな幸運はかんべん
してほしい。