モードレスダイアログのアクセス違反 – プログラミング – Home

モードレスダイアログのアクセス違反
 
通知
すべてクリア

[解決済] モードレスダイアログのアクセス違反

固定ページ 1 / 2

ばにら
 ばにら
(@ばにら)
ゲスト
結合: 14年前
投稿: 16
Topic starter  

WinXP、VC6、ダイアログベースで作成しています。

Create()を使用してモードレスダイアログを表示させているのですが、
2つのモードレスダイアログを同様の方法で記述したにも関わらず、
片方のみアクセス違反で表示できない状況となり困っています。

<ソースファイル(メイン)>
CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMainDlg::IDD, pParent)
{
/*(CModeless* )*/m_pModeless = new CModeless( this );
}

CMainDlg::~CMainDlg()
{
/*(CModeless* )*/m_pModeless = NULL;
}

void CMainDlg::OnBtnOpen()
{
/*(CModeless* )*/m_pModeless->Create();
}

<ソースファイル(モードレスダイアログ)>
BOOL CModeless::Create()
{
return CDialog::Create( CModeless::IDD, m_pParent );
//ここでアクセス違反となります
}

ちなみに、新しくダイアログを作成して同様の記述を行った場合
作成したダイアログが表示でき、元々作成していたダイアログがアクセス違反となりま
す。

色々調べてますが原因がわかりません。
お手数ですがアドバイスをよろしくお願いいたします。


引用未解決
トピックタグ
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

CDialog::Create()の呼び出しでアクセス違反の起きる理由は山ほど考えられ
ますので、それだけでは答えようがありません。

CDialog::Create()の中に潜っていって、具体的にアクセス違反を起している
行のコードを教えて下さい。

あと、アクセス違反が起きる前に Assertion Failed とか発生していませんか?
発生してるようならその行のコードも教えて下さい。


返信引用
ばにら
 ばにら
(@ばにら)
ゲスト
結合: 14年前
投稿: 16
Topic starter  

bunさん

ご回答ありがとうございます。
返信が遅くなり申し訳ありません。

>CDialog::Create()の中に潜っていって、具体的にアクセス違反を起している
>行のコードを教えて下さい。
「潜っていく」とは具体的にどのような方法をとれば良いのでしょうか?
素人質問ですみません・・

>あと、アクセス違反が起きる前に Assertion Failed とか発生していませんか?
>発生してるようならその行のコードも教えて下さい。
これは発生していないようです。

また、Create()の前にGetSafeHwnd()を追加すると「AFXWIN2.INL」の

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
⇒ { return this == NULL ? NULL : m_hWnd; }

でアクセス違反となります。
Create()はこれまで使ってきたことはあったのですが、
こういった症状は初めてでパニックになってます。

お手数ですがよろしくお願いいたします。


返信引用
ツ青」ツ戸ゑソス・ス
 ツ青」ツ戸ゑソス・ス
(@ツ青」ツ戸ゑソス・ス)
ゲスト
結合: 18年前
投稿: 178
 

>「潜っていく」とは具体的にどのような方法をとれば良いのでしょうか?

ステップ実行していく…ということかと。
今回の場合だと、ステップインで呼び出し先へと追いかけていくことになりますかね。

> return CDialog::Create( CModeless::IDD, m_pParent );
> //ここでアクセス違反となります

のreturnの行にブレークポイントを置いて実行。
ブレークしたらステップイン(F11キーだったかな)で進めていって、実際にアクセス違反
が発生する場所のソースコード名と行番号を調べて下さい。
ということでしょう。
# MFCのソースをインストールしていないとステップインできませんので…インストールし
ていない場合はインストールしてからになります。


返信引用
ツ青」ツ戸ゑソス・ス
 ツ青」ツ戸ゑソス・ス
(@ツ青」ツ戸ゑソス・ス)
ゲスト
結合: 18年前
投稿: 178
 

名前が化けたままでした(TT
上のは私です(TT

>また、Create()の前にGetSafeHwnd()を追加すると「AFXWIN2.INL」の

Create()の前だと…ハンドルがまだ作成されていないとかいうことはないですかね???


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

うーーん、
 VC6.0は、ステップがあまり効かないし、暴走するときがあります。
関数の中まで見れるかな?
ブレークで一つ一つ調べていくのがいいかと思いますね。
まぁー金銭的に厳しいですが、新しいVCを買ったほうがいいですね。

>また、Create()の前にGetSafeHwnd()を追加すると「AFXWIN2.INL」の

>_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
>⇒ { return this == NULL ? NULL :

これ、いいヒントですね。
一つ一つ段階的にブレークしていってどこから
this == NULL → m_hWnd == NULLになるか見て
おかしな処理をしていないか見てみるしかないように思います。


返信引用
ばにら
 ばにら
(@ばにら)
ゲスト
結合: 14年前
投稿: 16
Topic starter  

瀬戸っぷさん
ITOさん

ありがとうございます。

Create()前の値を見ると、
m_pModelessの値が0x00000003{CModeless hWnd=???}
となってます。

良く意味はわかりませんが、このhWnd=???がいけないような
気は、します・・。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

追記
 うーーん?
 Create()の前ですか、なら違いますね。
あとは、
 ・CModeless::IDDがもうひとつのダイアログとダブっていないか?
 ・m_pParentがLULLになっていないか。
ですかね。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>m_pModelessの値が0x00000003{CModeless hWnd=???}
>となってます。
そうですね。
ばにらさんの結果より遅くなってしまいました。


返信引用
ばにら
 ばにら
(@ばにら)
ゲスト
結合: 14年前
投稿: 16
Topic starter  

これは何が原因なのでしょうか?
どういった確認をすればよいのでしょうか?


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

> m_pModelessの値が0x00000003{CModeless hWnd=???}
「0x00000003 なんて位置のアドレスを指している」+「奇数アドレス」となると、
どっかでバッファオーバーランしている可能性をまず疑う。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>どういった確認をすればよいのでしょうか?

これはどうですか?

> あとは、
>  ・CModeless::IDDがもうひとつのダイアログとダブっていないか?
>  ・m_pParentがLULLになっていないか。
> ですかね。

Create()の前のthisポインタの値をチェックして何か気づくことはないですか?


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

Create()を呼ぶと、ざっと以下の処理が走ります。
1) ダイアログテンプレートを適用してリソースの表示
2) ダイアログの初期化
a) DDX/DDVを利用したメンバ変数の割り当てとデータチェック
b) OnInitDialog()内の処理
この膨大な処理のどこでもアクセス違反は起き得ます。

思いつく限り列挙すると、
1) CModeless::IDDのリソースIDを持ったダイアログリソースが存在しない
2) DDX/DDVで関連づけているコントロールIDのリソースが存在しない
(例) DDX_Control(pDX, IDC_BTN1, m_Btn1);
において、IDC_BTN1がダイアログリソース上に存在しない
3) CDialog::OnInitDialog()を呼ぶ前にDDXメンバ変数にアクセスしている
(例) 2)の例の実装があるとして、
BOOL CModeless::OnInitDialog()
{
m_Btn1.SetWindowText(Test); // <- アクセス違反
CDialog::OnInitDialog();
}
4) そもそも、CModeless::OnInitDialog()内の処理にバグがある

(などなど)

可能性がありすぎるので絞りきれないわけです ^^;


返信引用
ばにら
 ばにら
(@ばにら)
ゲスト
結合: 14年前
投稿: 16
Topic starter  

遅くなってすみません。

>どっかでバッファオーバーランしている可能性をまず疑う。
この場合もうお手上げですかね?
まだアプリケーション作り始めなので、最初から作り直すのもアリかなと
考え始めてます。
(解決策になるかはわかりませんが。)

>Create()の前のthisポインタの値をチェックして何か気づくことはないですか?
thisの値は 0x0012fb7c で、異常があるようには見えません。

>bunさん
ありがとうございます。
チェックできるところからやっていこうかと思います。


返信引用
gak
 gak
(@gak)
ゲスト
結合: 21年前
投稿: 132
 

>> どっかでバッファオーバーランしている可能性をまず疑う。
> この場合もうお手上げですかね?
VS2008 とかだと「デバッグ」->「ブレークポイントの作成」->「新しいデータ ブレーク
ポイント」で指定メモリアドレスが書き換えられた瞬間とコード場所を掴める。のだが、
VC6にこの機能あったっけ?

上記が無理なら

CMainDlg::CMainDlg(...) {
/*(CModeless* )*/m_pModeless = new CModeless( this );
m_pModelessBackup = m_pModeless;
}
CMainDlg::PreTranslateMessage(...) {
if (m_pModelessBackup != m_pModeless) { // 自分の知らない所で値が変わった
AfxMessageBox(_T(直前操作でバッファオーバーランされたかも));
}

}

等でもして、大体で探っていくしかないかも


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました