重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

Visual C++ を勉強しだした Windowsプログラム初心者です。

ある参考書のサンプルで、メールスロットを利用したメッセッンジャー体験プログラムがあります。
このプログラム一つで、クライアントとサーバーを実感する為のもので、ダイアログボックスだけで出来ています。

デバック実行で、画像にある[送信]ボタンを押すと、
「Mailslot.exe の 0x1021471c (msvcr71d.dll) でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000015 を読み込み中にアクセス違反が発生しました。 。」
とエラーボックスが出ます。

原因は パソコンのOSのバージョンなのか、何か足りないライブラリなのか?切り分け所がわからなくて困っています。

どなたか良いアドバイスをお願いします。

OS : Vista Home Premium
IDE: Visual C++.net スタンダード version 2003

因みに、stdafx.h の内容は↓です。
#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif


#ifndef WINVER
#define WINVER 0x0501
#endif

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif

#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0410
#endif

#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS

// 一般的で無視しても安全な MFC の警告メッセージの一部の非表示を解除します。
#define _AFX_ALL_WARNINGS

#include <afxwin.h>
#include <afxext.h>
#include <afxdisp.h>

#include <afxdtctl.h>
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>

#endif

#include <Lmcons.h>

「(msvcr71d.dll) でハンドル」の質問画像

A 回答 (2件)

>>コールスタックからコードでの呼び出し箇所を探して下さい。


>の具体的な解決法については知ってないです。

「中断」を押したらoutput.cが表示されたようですが、
下の方のウィンドウ(デフォルトならば左右2分割されている右側)にコールスタックとか呼び出し履歴とか書かれたタブがあるかと思われます。
そちらから1つずつ見ていくとどこかで自分の書いたコード(実行しているプロジェクトに含まれるソースコード)に行き当たると思われます。
そこで、変数の内容などを確認してみるといいでしょう。

>[中断]ボタン後、output.cエディタ↓
>下から 5行目のところで矢印が出ています。

手元のはVS2005ですが、ほぼ同じようなところが。
printf()やsprintf()でのフォーマット指定のsの処理("%s"の処理)のようです。

[送信]ボタンのイベントハンドラのコードを掲示された方が確実ですが…
イベントハンドラ内でsprintf()を使用しているならば、そちらで渡している引数に問題がある。
かと思われます。
sprintf()の第1引数にCString型の変数渡している。
sprintf()の第3引数以降に中身の設定されていないCString型の変数を渡している…とか。

>ユニコードが関係している?のでしょうか。

おそらく関係していないでしょう。
# が、char型での文字列を期待しているところにwchar_t型での文字列を渡すと、うもく動作しない可能性が高いですが。
    • good
    • 0
この回答へのお礼

ありがとうございます。

申し訳ございません。コードミスでした。

>コールスタックとか呼び出し履歴とか書かれたタブがあるかと思われます。
>そちらから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が足りない )。

お礼日時:2009/10/14 12:20

stdafx.hの内容は関係ありません。



手元のmsvcr71d.dllはC:\WINDOWS\Microsoft.NET\Framework\v1.1.4322にあるものだけなので、
そちらと同じかどうかは解りませんが…
アドレスから見るとfcloseall()の中で発生しているようです。
# 明示的にfcloseall()を呼び出すこともないと思われますので…たぶんバージョン違いですな。

で、たいていこういう場合は使用者側のミスであることが多いですが…
エラーダイアログで「中止」ボタンなどでデバッガが起動すると思われるので、
コールスタックからコードでの呼び出し箇所を探して下さい。

リンクされているmsvcr71d.dllをDependency Walkerに食わせるとエクスポートされている関数一覧が出てきます。
右の方に「Entry Point」とありますので、下に表示される「Preferred Base」のアドレスに加算することで、エラーダイアログに表示されているアドレスから該当関数の想定が可能と思われます。
# 実行時の環境によってはこの手は使えないかも知れません。
# DLLのロードアドレスは毎回同じとは限りませんので。(アプリでそのアドレス使用されていたら別の場所に読み込まれる)
    • good
    • 0
この回答へのお礼

アドバイスありがとうございます。

しかし、私は
>コールスタックからコードでの呼び出し箇所を探して下さい。
の具体的な解決法については知ってないです。

[自動変数] ウィンドウには、
名前  値                                          型
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 */
        }

ユニコードが関係している?のでしょうか。

お礼日時:2009/10/13 14:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!