C++例外の回避方法
VS2005でtest.exe から test.dll(VC++)を呼んで、プログラムを作っています。
しかし、デバッグの時に、以下の例外が発生しました。
test.exe の 0x7c812a5b で初回の例外が発生しました:
Microsoft C++ の例外: int (メモリの場所 0x00115820)。
以上の例外は、どういう意味でしょうか?
メモリのアクセスのエラーでしょうか?
ソースコードは以下のようになります。
test.dllプログラムの構造としては、以下のようになります。
char readrecordTemp[READ_SIZE + 1];
memset(readrecordTemp,0x00,sizeof(readrecordTemp));
char returncode1 = 0;
char returncode2 = 0;
try{
for(;;){
if (NULL == fgets(readrecordTemp,VT_MAX_READ_SIZE, m_fp)){
if (ferror(m_fp)){
throw ERROR_IO;
}
if (feof(m_fp)){
throw EOF;
}
}
returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];
returncode2 =readrecordTemp[strlen(readrecordTemp) -1 ];
。。。。
。。。。
}
ファイルの最後になったら、自分が定義した例外で
returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];
returncode2 =readrecordTemp[strlen(readrecordTemp) -1 ];
などを飛ばしたいですが、デバッグの時に、
returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];のところで
以上の例外が出されました。readrecordTempが短すぎると長すぎると
問題になるといわれてましたが、実際にどういう問題でしょうか?
readrecordTempは2より短いときに、問題だが、ではどうやって
回避できるでしょうか?
readrecordTempの最後の二つの符号を取りたいですが、
どうすればいいですか?
投稿日時 - 2009-01-04 11:46:18
>readrecordTempの最後の二つの符号を取りたい
>改行コードが入ることです。
fgetsなどのC言語のファイルストリーム関数では
「改行コードは、LFのみの1バイト」
です。
扱っているファイル内の改行コードが「CR+LF」の2バイトであっても、C言語のファイルストリーム関数は、内部で「LFのみ」に変換します(但し、ファイルをバイナリモードで開いている場合を除く)
なので
「改行が2バイトだと思いこんでいる限り、思った通りには動かない」
でしょう。
質問者さんのプログラムでは「改行のみの行」をfgetsした場合、readrecordTempの中身は「"\n"+EOS」になり、strlen(readrecordTemp)は「1」になります。
質問者さんは「改行のみの行を読んだら、readrecordTempの中身は"\r\n"+EOSになり、strlen(readrecordTemp)は2になる。1になる事は無い」と勘違いしていますから
returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];
の行で例外が起きる筈はない、と思い込んでいます。
しかし、readrecordTempは「"\n"+EOS」や「""+EOS」になる事があり、strlen(readrecordTemp)は1や0など、2未満になる可能性があります。
strlen(readrecordTemp)が1や0になれば
returncode1 =readrecordTemp[strlen(readrecordTemp) -2 ];
や
returncode2 =readrecordTemp[strlen(readrecordTemp) -1 ];
の行で
readrecordTemp[ -2 ]
や
readrecordTemp[ -1 ]
に対してアクセスするので、例外が発生して当然です。
まずは「改行コードは1バイトである」と「fgetsしたら、読み込んだ文字列の文字列長が0や1になる事がある」と言う事を理解しましょう。
これが理解出来て居ないので、同じような質問を何度も繰り返し、そのたびに明確な回答が得られず、再質問の繰り返しになるのです。
投稿日時 - 2009-01-05 11:44:14
このQ&Aは役に立ちましたか?
0人が「このQ&Aが役に立った」と投票しています
回答(3)
> 実際にどういう問題でしょうか?
readrecordTemp[]で確保していないメモリ領域へのアクセスが発生します。
2未満の方は言うまでもありませんが、VT_MAX_READ_SIZEがREAD_SIZEより大きい場合にも問題が出る可能性がありますね。
#というかこの二つは同じ定数使った方がいいんでは?
> どうやって回避できるでしょうか?
strlen(readrecordTemp)の値を見て、異常が出る値(2未満とかREAD_SIZE+1以上とか)ならエラー処理をすればよいのでは。
どんなエラー処理が必要なのかはこれだけではなんとも言いようがないのでご自身で考えてください。
投稿日時 - 2009-01-04 12:38:38