バグの原因がわからない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dic
記事: 534
登録日時: 8年前
住所: 宮崎県

バグの原因がわからない

#1

投稿記事 by dic » 2ヶ月前

バグが発生します。例外が発生しているので、どこかでアクセス違反がおきていると
思いますがどこなのかがわかりません。
どこかまずいところはないでしょうか?
unsigned int i;の値が lstrcpy(buf,... のところを処理するといきなり
vList.size() より大きい183157と値が書き換えられます。

コード:

void hoge_3(vector<wstring> vList, vector<CMap> *pMap )
{
	vector<wstring>	vHttp;
	unsigned int i;
	TCHAR buf[DEF_BUFSIZE];
	for (i = 0; i < vList.size(); i++) {
		memset(buf, 0, DEF_BUFSIZE);
		lstrcpy(buf, vList.at(i).c_str());
		TCHAR *p;
		p = wcsstr(buf, L"http://moeimg.net/");
		if (p) {
			//余計なものを取り除く
			hoge_3_1(&vHttp, p);
		}
		if (i > vList.size())
		{
			// バグっている
			i = vList.size();
		}
	}
	if (vHttp.size() == 0)
		return; // ここで抜けるときにアクセス違反がでる


例外がスローされました。
0x001E3AC2で例外がスローされました(WCHARの練習.exe内)0xC0000005:
場所0xDDDDDDDDへの書き込み中にアクセス違反が発生しました。

dic
記事: 534
登録日時: 8年前
住所: 宮崎県

Re: バグの原因がわからない

#2

投稿記事 by dic » 2ヶ月前

自己解決しました。
入力データがおかしかったです。

かずま

Re: バグの原因がわからない

#3

投稿記事 by かずま » 2ヶ月前

dic さんが書きました:
2ヶ月前
自己解決しました。
入力データがおかしかったです。
フォーラム(掲示板)ルールにあるように、「解決しました」だけで
終わらず、どのようにして解決したかを書いていただけませんか?

vList.at(i) の wstring の長さが DEF_BUFSIZE 以上だったため、
buf がバッファオーバーフローし、buf の次にあった i の値を
壊していたのだと私は推測していますが、違いますか?
オフトピック
今回のバグとは無関係ですが、memset の使い方が間違っています。
UNICODE を使う設定だと、TCHAR は sizeof(wchar_t) で 2バイト
ですから、sizeof(buf) は 2 * DEF_BUFSIZE になるはずです。

buf 全体を初期化したければ、
memset(buf, 0, sizeof buf); または
memset(buf, 0, sizeof(TCHAR) * DEF_BUFSIZE);
のように書くべきです。

というか、次の lstrcpy で buf には文字列が格納されるので
memset による初期化は不要です。

hoge_3 の第1引数が vector<wstring> vList になっていますが、
これでは、呼び出し元の vector 全体がコピーされてしまいます。
参照にして const vector<wstring> &vList にしたほうが効率が
良くなります。

dic
記事: 534
登録日時: 8年前
住所: 宮崎県

Re: バグの原因がわからない

#4

投稿記事 by dic » 2ヶ月前

>>かずまさま
関数hoge_2のところで値を読み込むのですが、
ここでも memset( buf, 0, DEF_BUFSIZE );
としていたところで、これで予期しないバグが混入していました。
改善して memset( buf, 0, sizeof(TCHAR) * DEF_BUFSIZE );
に変更したところhoge_3での読み込んだ値を使う場所での
バグがなくなりました。
おっしゃるとおり、bufにバグが混入しており、i の値を
書き換えたと思えます。

解決策は、memset( buf, 0, sizeof(TCHAR)*DEF_BUFSIZE);に書き換えた
です。
書き換える前は データ内に??????????????????????????????????????????????????????と
不明なデータが入っており、読み込むデータもかなり変則的でこれで
正常と判断していたところでした。が、バグのようでした。

また、参照渡しにすることにも対応しました。
変更されては困るので const 参照で渡しました。

バグの原因は推測のとおりでした。助かりました。ありがとうございました。

かずま

Re: バグの原因がわからない

#5

投稿記事 by かずま » 2ヶ月前

dic さんが書きました:
2ヶ月前
解決策は、memset( buf, 0, sizeof(TCHAR)*DEF_BUFSIZE);に書き換えた
です。
memset(buf, 0. sizeof(TCHAR) * DEF_BUFSIZE) は buf 全体を 0 で初期化し、
memset(buf, 0. DEF_BUFSIZE) は buf の半分を 0 で初期化します。
buf の範囲外に 0 を書き込むわけでもありません。
memset(buf, 0. sizeof(TCHAR) * DEF_BUFSIZE) に書き換えて問題が解決
するとは思えません。

DEF_BUFSIZE はいくつですか?
lstrcpy でコピーする文字列は何文字ですか?

具体的な情報の提示をお願いします。

返信

“C言語何でも質問掲示板” へ戻る