ハンドルされていない例外の再発
ハンドルされていない例外の再発
毎度すみません。以前http://dixq.net/forum/viewtopic.php?f=3&t=15492にて、ハンドルされていない例外
のことで質問をした者です。申し訳ありませんが、テンプレやコードの詳細は上記のURLをたどってみていただけると幸いです。(まだトピックの一覧の1ページ目に残っているので
それを見たほうが早いかもですが)
今回、上記の問題が再発してしまったため、またトピックを立たせていただきました。
以前のトピックにて問題が解決され、今朝までは思い通りに動いていたのですが、あることをした結果、また「ハンドルされていない例外」や、
「Stack around the variable 'data' was corrupted.」などがでてくるようになってしまいました。
順を追って、きっかけや症状を説明します。
早朝のことなので、すこしうろ覚えなのですが、
1、敵オブジェクトを作る際、何体までなら重くならないかを調べたかったため、敵の数を極端にふやした。(たしかENEMY_NUMを600にした。当然、CSVも600行。馬鹿なことやったなあと思います。)
2、フルスクリーンモードで実行した。結果、重くなりすぎて、フリーズした。待っても、プログラムを終了させようとしても無駄だったため、仕方なくPCを強制終了した。
3、起動し、ENEMY_NUMを5に戻した。当然CSVも5行に。
4、実行したら、「Stack around the variable 'data' was corrupted.」がでるようになった。
5、コードはそこ以外変えていない(はず)
6、ステップ実行でnを調べると、なぜかn==5にまでなっていた。(前回はn==6にまでなっていたが、原因はCSVの打ち損じミスだった)結果data[5]にまでなってしまって、ENEMY_NUMをオーバーしている.
ここがエラーの原因なのはわかるが、もとに戻したはずなのになぜこうなるかわからない。
7、600行にしたり、5行にもどした際、また何かミスがあったのかとCSVをチェックしても異常は見当たらない。
8、ためしに、CSVファイルを一度消し、龍神録プロジェクトのdatからコピーして5行に変更したCSVファイルを入れなおした。
9、結果、一度だけ異常なくプログラムが動いたが、ためしに、新しくしたCSVデータを、1行目のyの値だけ数値を変えて(特にその変更に意図はない)実行した結果、再び同じエラーが出るようになった。
10、いくらリビルドなどしても、CSVのテキストを見直しても、うまく行かず、質問しました。
正直、まったく検討がつきません。毎度すみませんが、アドバイスのようなものをいただきたいです。
どうかよろしくお願いします。
のことで質問をした者です。申し訳ありませんが、テンプレやコードの詳細は上記のURLをたどってみていただけると幸いです。(まだトピックの一覧の1ページ目に残っているので
それを見たほうが早いかもですが)
今回、上記の問題が再発してしまったため、またトピックを立たせていただきました。
以前のトピックにて問題が解決され、今朝までは思い通りに動いていたのですが、あることをした結果、また「ハンドルされていない例外」や、
「Stack around the variable 'data' was corrupted.」などがでてくるようになってしまいました。
順を追って、きっかけや症状を説明します。
早朝のことなので、すこしうろ覚えなのですが、
1、敵オブジェクトを作る際、何体までなら重くならないかを調べたかったため、敵の数を極端にふやした。(たしかENEMY_NUMを600にした。当然、CSVも600行。馬鹿なことやったなあと思います。)
2、フルスクリーンモードで実行した。結果、重くなりすぎて、フリーズした。待っても、プログラムを終了させようとしても無駄だったため、仕方なくPCを強制終了した。
3、起動し、ENEMY_NUMを5に戻した。当然CSVも5行に。
4、実行したら、「Stack around the variable 'data' was corrupted.」がでるようになった。
5、コードはそこ以外変えていない(はず)
6、ステップ実行でnを調べると、なぜかn==5にまでなっていた。(前回はn==6にまでなっていたが、原因はCSVの打ち損じミスだった)結果data[5]にまでなってしまって、ENEMY_NUMをオーバーしている.
ここがエラーの原因なのはわかるが、もとに戻したはずなのになぜこうなるかわからない。
7、600行にしたり、5行にもどした際、また何かミスがあったのかとCSVをチェックしても異常は見当たらない。
8、ためしに、CSVファイルを一度消し、龍神録プロジェクトのdatからコピーして5行に変更したCSVファイルを入れなおした。
9、結果、一度だけ異常なくプログラムが動いたが、ためしに、新しくしたCSVデータを、1行目のyの値だけ数値を変えて(特にその変更に意図はない)実行した結果、再び同じエラーが出るようになった。
10、いくらリビルドなどしても、CSVのテキストを見直しても、うまく行かず、質問しました。
正直、まったく検討がつきません。毎度すみませんが、アドバイスのようなものをいただきたいです。
どうかよろしくお願いします。
Re: ハンドルされていない例外の再発
このコード
と
このcsv
を使うと、必ず再発する
という
コード
と
csv
を提示するのが
よい、と思います。
と
このcsv
を使うと、必ず再発する
という
コード
と
csv
を提示するのが
よい、と思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
今までバグが発覚しなかっただけで潜在バグが表面化しただけです。
根本的にバグを散らないと何時迄も付きまといそうです。
まぁ、完全にcsvの読み込みを理解してエラーになる部分のガードを増強して作りなおしたほうが良いんでしょうね。
根本的にバグを散らないと何時迄も付きまといそうです。
まぁ、完全にcsvの読み込みを理解してエラーになる部分のガードを増強して作りなおしたほうが良いんでしょうね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
これから何度も作りなおすと思いますので、その時ベストな方法で出来ていれば問題無いと思います。
>それとも、実際に問題のある、ロード関数だけを作り直すのが無難でしょうか。
問題をまず突き止めましょう。
>それとも、実際に問題のある、ロード関数だけを作り直すのが無難でしょうか。
問題をまず突き止めましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
問題は、nがENEMY_NUMを超えてしまうことということしか思い浮かびません・・・。
ロード関係の処理は勉強中なのですが、ロード周りの根本は龍神録のソースから持ってきたものなので、
やはり、CSVの何らかのミスや龍神録との相違点である、dataという構造体変数関連でミスをしているのか・・・。
ロード関係の処理は勉強中なのですが、ロード周りの根本は龍神録のソースから持ってきたものなので、
やはり、CSVの何らかのミスや龍神録との相違点である、dataという構造体変数関連でミスをしているのか・・・。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
なぜnが超えてしまうかが調べられていません。
つまり、ガードが甘い読み込み処理なので、問題点を探して下さい。
つまり、ガードが甘い読み込み処理なので、問題点を探して下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
自分で考えなければならないことなので、今すぐ安直に、問題の根本的な回答を伺うことはしませんが、
不躾な質問になってしまうのですが、ソフト屋さんにとって、今回のエラーをなくす方法やああすればいいのにといったものが明確にあり、それは「自分で考えろ」ということなのでしょうか。
失礼な質問ですみません。
不躾な質問になってしまうのですが、ソフト屋さんにとって、今回のエラーをなくす方法やああすればいいのにといったものが明確にあり、それは「自分で考えろ」ということなのでしょうか。
失礼な質問ですみません。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
元(龍神録)からの問題ですが、読み込み処理にイレギュラーな値や動作のガードがありませんので、何か問題があればこんな風に困ることになります。SDD さんが書きました:自分で考えなければならないことなので、今すぐ安直に、問題の根本的な回答を伺うことはしませんが、
不躾な質問になってしまうのですが、ソフト屋さんにとって、今回のエラーをなくす方法やああすればいいのにといったものが明確にあり、それは「自分で考えろ」ということなのでしょうか。
失礼な質問ですみません。
何度か、それらしいことは書いていますよ。
>つまり、ガードが甘い読み込み処理なので、問題点を探して下さい。
>まぁ、完全にcsvの読み込みを理解してエラーになる部分のガードを増強して作りなおしたほうが良いんでしょうね。
ガードが甘いと何度も書いてますよね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
ガードが甘いことが問題・原因ならば、なぜnがENEMY_NUMを超えてしまうのかを把握して、ガードを強めさえすれば(nがENEMY_NUMを超えないようにする)
解決し、正常に動くという解釈で良いのでしょうか。
解決し、正常に動くという解釈で良いのでしょうか。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
そのガードを入れる過程で潜在バグがあればイレギュラーな動作としてガードが働き問題が表面化するはずですので、問題は解決するはずです。SDD さんが書きました:ガードが甘いことが問題・原因ならば、なぜnがENEMY_NUMを超えてしまうのかを把握して、ガードを強めさえすれば(nがENEMY_NUMを超えないようにする)
解決し、正常に動くという解釈で良いのでしょうか。
ただ、今現在問題が再現している状況ならば、潜在バグの部分を見つける事は難しくないはずです。
ちゃんと読み込み処理のコードの動作をデバッグで順序良く追いかけれているのなら気づく問題だと思います。
なぜなら、問題の有る所でイレギュラーな動作をしたりイレギュラーな値が読み込まれるはずですから。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
わかりました。
またしばらく、見ていこうと思います。
正直、このトピックで最初に書いたように、下手な実験をしたせいで色々おかしくなったのか
と不安に思っていたのですが、今までたまたまうまくいっていただけならまだなんとかしようがあるので、
とりあえず致命的なバグを発見することにつながってよかったと思います。
すみませんが、念のため、まだ未解決にしておきます。
またしばらく、見ていこうと思います。
正直、このトピックで最初に書いたように、下手な実験をしたせいで色々おかしくなったのか
と不安に思っていたのですが、今までたまたまうまくいっていただけならまだなんとかしようがあるので、
とりあえず致命的なバグを発見することにつながってよかったと思います。
すみませんが、念のため、まだ未解決にしておきます。
Re: ハンドルされていない例外の再発
すみません、今度のトラブルもまたCSVテキストが原因でした。最後の行に続き、空白の行が何行かあり、それをしっかりと消すと元通りに動くように
なりました。(いかんせん空白なため、キーを押してカーソルを移動させないと気付けなかった)CSVをテキストエディタでいじくることはあんまり良くないようです。
一度、わざと、行を同じように乱して、実行すると、それまでと同じエラーメッセージが出て、その行を元通りに正してやると、また正しく動き始めました。
600行増やし、それを5行に戻した際、余計な空白を消しきれてなかったのだと思います。
しかし、やはり脆弱なコードなため、ガードの処理を考えています。
考えた結果のガードのコードを評価していただきたいので、まだ未解決とします。
なりました。(いかんせん空白なため、キーを押してカーソルを移動させないと気付けなかった)CSVをテキストエディタでいじくることはあんまり良くないようです。
一度、わざと、行を同じように乱して、実行すると、それまでと同じエラーメッセージが出て、その行を元通りに正してやると、また正しく動き始めました。
600行増やし、それを5行に戻した際、余計な空白を消しきれてなかったのだと思います。
しかし、やはり脆弱なコードなため、ガードの処理を考えています。
考えた結果のガードのコードを評価していただきたいので、まだ未解決とします。
Re: ハンドルされていない例外の再発
一応、再度コードを貼ります。
void EnemyControl::Make_Enemy(){
EnemyData data[ENEMY_NUM];
int n,num,i,fp;
char fname[]={"story1.csv"};
int input[64];
char inputc[64];
fp = FileRead_open(fname);//ファイル読み込み
if(fp == NULL){
printfDx("read error\n");
return;
}
for(i=0;i<2;i++)//最初の2行読み飛ばす
while(FileRead_getc(fp)!='\n');
n=0 , num=0;
while(1){
for(i=0;i<64;i++){
inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
if(inputc[i]=='/'){//スラッシュがあれば
while(FileRead_getc(fp)!='\n');//改行までループ
i=-1;//カウンタを最初に戻して
continue;
}
if(input[i]==',' || input[i]=='\n'){//カンマか改行なら
inputc[i]='\0';//そこまでを文字列とし
break;
}
if(input[i]==EOF){//ファイルの終わりなら
goto EXFILE;//終了
}
}
switch(num){
case 0: data[n].cnt =atoi(inputc);break;
case 1: data[n].pattern =atoi(inputc);break;
case 2: data[n].knd =atoi(inputc);break;
case 3: data[n].x =atof(inputc);break;
case 4: data[n].y =atof(inputc);break;
case 5: data[n].sp =atof(inputc);break;
case 6: data[n].bltime =atoi(inputc);break;
case 7: data[n].blknd =atoi(inputc);break;
case 8: data[n].col =atoi(inputc);break;
case 9: data[n].hp =atoi(inputc);break;
case 10:data[n].blknd2 =atoi(inputc);break;
case 11:data[n].wait =atoi(inputc);break;
case 12:data[n].item_n[0]=atoi(inputc);break;
case 13:data[n].item_n[1]=atoi(inputc);break;
case 14:data[n].item_n[2]=atoi(inputc);break;
case 15:data[n].item_n[3]=atoi(inputc);break;
case 16:data[n].item_n[4]=atoi(inputc);break;
case 17:data[n].item_n[5]=atoi(inputc);break;
}
num++;
if(num==18){
num=0;
n++;
}
}
EXFILE:
FileRead_close(fp);
//敵オブジェクト生成
for(int i=0;i<ENEMY_NUM;i++){
enemy[i]=new Enemy(data[n].cnt,data[n].pattern,data[n].knd,data[n].x,
data[n].y,data[n].sp,data[n].bltime,data[i].blknd,data[n].col,
data[n].hp,data[n].blknd2,data[n].wait,data[n].item_n);
}
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
エラーですのでエラーログを画面に表示して、ログファイルを出して終了すべきかと思います。Log.txtに書き出す方法もあります。
つまり、エラーで戻るのですがC++ならthrowしてはどうでしょう。
あと、列のデータの個数やデータ型が合わない時もエラーにすべきです。
【補足】
戻り値をエラーにして返す方法もあります。
つまり、エラーで戻るのですがC++ならthrowしてはどうでしょう。
あと、列のデータの個数やデータ型が合わない時もエラーにすべきです。
【補足】
戻り値をエラーにして返す方法もあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
返信ありがとうございます。
条件をさらに厳しくするべきなのはわかりました。
とりあえず、当初の条件であった「nが超えないように」というのに絞ってやってみたところ、例外処理が不慣れなこともあって、
なぜかスルーしてしまいます。(スローしてほしいのに)
わざと、CSVに無駄な空白を持たせ、nがENEMY_NUMを超えるようにし、例外されていないハンドルを起こすと、例外処理を無視して「ハンドルされていない例外」という
いつものエラーが起きるだけでした。
記述に問題があるからこの結果なのでしょうが、間違いがわかりません・・・。
条件をさらに厳しくするべきなのはわかりました。
とりあえず、当初の条件であった「nが超えないように」というのに絞ってやってみたところ、例外処理が不慣れなこともあって、
なぜかスルーしてしまいます。(スローしてほしいのに)
わざと、CSVに無駄な空白を持たせ、nがENEMY_NUMを超えるようにし、例外されていないハンドルを起こすと、例外処理を無視して「ハンドルされていない例外」という
いつものエラーが起きるだけでした。
記述に問題があるからこの結果なのでしょうが、間違いがわかりません・・・。
void EnemyControl::Make_Enemy(){
EnemyData data[ENEMY_NUM];
int n,num,i,fp;
char fname[]={"story1.csv"};
int input[64];
char inputc[64];
fp = FileRead_open(fname);//ファイル読み込み
if(fp == NULL){
printfDx("read error\n");
return;
}
for(i=0;i<2;i++)//最初の2行読み飛ばす
while(FileRead_getc(fp)!='\n');
n=0 , num=0;
try{//例外処理
while(1){
if(n>ENEMY_NUM){
throw(1);
}
for(i=0;i<64;i++){
inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
if(inputc[i]=='/'){//スラッシュがあれば
while(FileRead_getc(fp)!='\n');//改行までループ
i=-1;//カウンタを最初に戻して
continue;
}
if(input[i]==',' || input[i]=='\n'){//カンマか改行なら
inputc[i]='\0';//そこまでを文字列とし
break;
}
if(input[i]==EOF){//ファイルの終わりなら
goto EXFILE;//終了
}
}
switch(num){
case 0: data[n].cnt =atoi(inputc);break;
case 1: data[n].pattern =atoi(inputc);break;
case 2: data[n].knd =atoi(inputc);break;
case 3: data[n].x =atof(inputc);break;
case 4: data[n].y =atof(inputc);break;
case 5: data[n].sp =atof(inputc);break;
case 6: data[n].bltime =atoi(inputc);break;
case 7: data[n].blknd =atoi(inputc);break;
case 8: data[n].col =atoi(inputc);break;
case 9: data[n].hp =atoi(inputc);break;
case 10:data[n].blknd2 =atoi(inputc);break;
case 11:data[n].wait =atoi(inputc);break;
case 12:data[n].item_n[0]=atoi(inputc);break;
case 13:data[n].item_n[1]=atoi(inputc);break;
case 14:data[n].item_n[2]=atoi(inputc);break;
case 15:data[n].item_n[3]=atoi(inputc);break;
case 16:data[n].item_n[4]=atoi(inputc);break;
case 17:data[n].item_n[5]=atoi(inputc);break;
}
num++;
if(num==18){
num=0;
n++;
}
}
}
catch(int err){
MessageBox(NULL,"nがENEMY_NUMを超えました。CSVを確認してください","メッセージ",MB_OK);
return;
}
EXFILE:
FileRead_close(fp);
//敵オブジェクト生成
for(int i=0;i<ENEMY_NUM;i++){
enemy[i]=new Enemy(data[i].cnt,data[i].pattern,data[i].knd,data[i].x,
data[i].y,data[i].sp,data[i].bltime,data[i].blknd,data[i].col,
data[i].hp,data[i].blknd2,data[i].wait,data[i].item_n);
}
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
失礼。見逃してました。
ヒントは添字は0からですよ。
ヒントは添字は0からですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
> の処理の時点ではnが5になっているので、その書き方にすると、テキストが正しくてもメッセージボックスが出てきてしまうようです。
すいません、意味不明です。
if(n>=ENEMY_NUM)、で弾いたら、そこから下には行かないはずです。
すいません、意味不明です。
if(n>=ENEMY_NUM)、で弾いたら、そこから下には行かないはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
えーと・・・
指摘されたところが(添字のこと) if(n>ENEMY_NUM)だと思ったので、
if(n>=ENEMY_NUM)とすると、例外の判定のところに来たときはnが5になっているので弾かれてしまうため、n[4]までただしくロードされていても、メッセージボックスの処理まで飛んでしまう
と言いたかったのですが、まだ語弊があるかもしれません
指摘されたところが(添字のこと) if(n>ENEMY_NUM)だと思ったので、
if(n>=ENEMY_NUM)とすると、例外の判定のところに来たときはnが5になっているので弾かれてしまうため、n[4]までただしくロードされていても、メッセージボックスの処理まで飛んでしまう
と言いたかったのですが、まだ語弊があるかもしれません
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
あぁ、じゃあ先にEOFその他の入力処理してからif(n>=ENEMY_NUM)でい良いのでは? 問題がありますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ハンドルされていない例外の再発
EOF関連の文より下にその判定文を持ってくるということですよね。
ついさっき、それをやって思い通りに動いたため、それでも問題があるかどうか聞きたかったのですが、
問題はない・・・ということでよいのでしょうか。
ついさっき、それをやって思い通りに動いたため、それでも問題があるかどうか聞きたかったのですが、
問題はない・・・ということでよいのでしょうか。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ハンドルされていない例外の再発
自分で考えて、自分で検証して、これこれこういう結果で問題無いと思います。SDD さんが書きました:EOF関連の文より下にその判定文を持ってくるということですよね。
ついさっき、それをやって思い通りに動いたため、それでも問題があるかどうか聞きたかったのですが、
問題はない・・・ということでよいのでしょうか。
まで持っていかないと、エラー処理を自分で組んでいることになりませんので、この時点での答えは差し控えます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。