- ベストアンサー
(msvcr71d.dll) でハンドルされていない例外が発生しました
- Visual C++ の初心者がメールスロットを利用したメッセンジャー体験プログラムを実行中にエラーが発生
- 原因はOSのバージョンか足りないライブラリの可能性があり、解決策を探している
- Vista Home PremiumのOSとVisual C++.net スタンダード version 2003のIDEを使用
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>>コールスタックからコードでの呼び出し箇所を探して下さい。 >の具体的な解決法については知ってないです。 「中断」を押したらoutput.cが表示されたようですが、 下の方のウィンドウ(デフォルトならば左右2分割されている右側)にコールスタックとか呼び出し履歴とか書かれたタブがあるかと思われます。 そちらから1つずつ見ていくとどこかで自分の書いたコード(実行しているプロジェクトに含まれるソースコード)に行き当たると思われます。 そこで、変数の内容などを確認してみるといいでしょう。 >[中断]ボタン後、output.cエディタ↓ >下から 5行目のところで矢印が出ています。 手元のはVS2005ですが、ほぼ同じようなところが。 printf()やsprintf()でのフォーマット指定のsの処理("%s"の処理)のようです。 [送信]ボタンのイベントハンドラのコードを掲示された方が確実ですが… イベントハンドラ内でsprintf()を使用しているならば、そちらで渡している引数に問題がある。 かと思われます。 sprintf()の第1引数にCString型の変数渡している。 sprintf()の第3引数以降に中身の設定されていないCString型の変数を渡している…とか。 >ユニコードが関係している?のでしょうか。 おそらく関係していないでしょう。 # が、char型での文字列を期待しているところにwchar_t型での文字列を渡すと、うもく動作しない可能性が高いですが。
その他の回答 (1)
- Wr5
- ベストアンサー率53% (2173/4061)
stdafx.hの内容は関係ありません。 手元のmsvcr71d.dllはC:\WINDOWS\Microsoft.NET\Framework\v1.1.4322にあるものだけなので、 そちらと同じかどうかは解りませんが… アドレスから見るとfcloseall()の中で発生しているようです。 # 明示的にfcloseall()を呼び出すこともないと思われますので…たぶんバージョン違いですな。 で、たいていこういう場合は使用者側のミスであることが多いですが… エラーダイアログで「中止」ボタンなどでデバッガが起動すると思われるので、 コールスタックからコードでの呼び出し箇所を探して下さい。 リンクされているmsvcr71d.dllをDependency Walkerに食わせるとエクスポートされている関数一覧が出てきます。 右の方に「Entry Point」とありますので、下に表示される「Preferred Base」のアドレスに加算することで、エラーダイアログに表示されているアドレスから該当関数の想定が可能と思われます。 # 実行時の環境によってはこの手は使えないかも知れません。 # DLLのロードアドレスは毎回同じとは限りませんので。(アプリでそのアドレス使用されていたら別の場所に読み込まれる)
お礼
アドバイスありがとうございます。 しかし、私は >コールスタックからコードでの呼び出し箇所を探して下さい。 の具体的な解決法については知ってないです。 [自動変数] ウィンドウには、 名前 値 型 p 0x00000037 <不適切な Ptr> char * text {sz=0x00000037 <不適切な Ptr> wz=0x00000037 <不適切な Ptr> } __unnamed text.sz 0x00000037 <不適切な Ptr> char * などと出ています。 テスト文字列を入力し[送信]ボタンをクリックすると、エラーダイアログ。「Mailslot.exe の 0x1021471c (msvcr71d.dll) でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000015 を読み込み中にアクセス違反が発生しました。 。」 [中断]ボタン後、output.cエディタ↓ 下から 5行目のところで矢印が出ています。 /* UNDONE: handle '#' case properly */ /* scan for null upto i characters */ #ifdef _UNICODE if (flags & FL_SHORT) { if (text.sz == NULL) /* NULL passed, use special string */ << 省略 >> /* textlen now contains length in wide chars */ } #else /* _UNICODE */ if (flags & (FL_LONG|FL_WIDECHAR)) { if (text.wz == NULL) /* NULL passed, use special string */ text.wz = __wnullstring; << 省略 >> /* textlen now contains length in wide chars */ } else { if (text.sz == NULL) /* NULL passed, use special string */ text.sz = __nullstring; p = text.sz; ( ここ⇒ ) while (i-- && *p) ++p; textlen = (int)(p - text.sz); /* length of the string */ } ユニコードが関係している?のでしょうか。
お礼
ありがとうございます。 申し訳ございません。コードミスでした。 >コールスタックとか呼び出し履歴とか書かれたタブがあるかと思われます。 >そちらから1つずつ見ていくとどこかで自分の書いたコード(実行しているプロジェクトに含まれるソースコード)に行き当たると思われます。 このようなデバックの方法が、私の本には書いてないので困ってます。 間違った部分のコードを下に書きます。 Mailslot.cpp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //メールスロットに書き込まれたメッセージを受信してリストボックスに追加する void CMailslotDlg::ReceiveMessage( void ) { TCHAR szMessage[ 1024 ]; DWORD dwReaded; BOOL fSuccess = ReadFile( m_hMailSlot, szMessage, sizeof( szMessage )-1, &dwReaded, NULL ); if( fSuccess == FALSE ) { LRESULT lResult = GetLastError(); if( (lResult == ERROR_ACCESS_DENIED) || (lResult == ERROR_SEM_TIMEOUT) ) { return; } CString text; text.Format( _T( "ReadFile code = %d" ), GetLastError() ); MessageBox( text ); return; } SYSTEMTIME stime; GetLocalTime( &stime ); CString buff; LPTSTR lptszUser = strtok( szMessage, "\n"); LPTSTR lptszData = strtok( NULL, "\n"); buff.Format( "%04d/%02d/%02d %02d:%02d:%02d %s/%s" , stime.wYear, stime.wMonth, stime.wDay, stime.wHour, stime.wMinute, stime.wSecond, lptszUser ? lptszUser : _T( "[ID 不明]"), lptszData ? lptszData : _T( "[メッセージなし]") ); CListBox *pList = (CListBox*)GetDlgItem( IDC_LISTMESSAGE ); pList->AddString( buff ); } //↑を↓のイベントハンドラで監視(?) void CMailslotDlg::OnTimer(UINT nIDEvent) { << 省略 >> } 間違った部分は、 buff.Format( "%04d/%02d/%02d %02d:%02d:%02 %s/%s" , の:%02 ←です( dが足りない )。