为什么调用GetDlgItem会导致访问冲突?

时间:2017-06-07 14:40:04

标签: mfc

我正在尝试访问我的一个MFC视图的对话框元素。为此,我运行以下代码行:

    ((CButton*)GetDlgItem( IDC_RADIO_VIEW2 ))->SetCheck( 0 );

这会导致以下异常:

  

在NameOfMyApplication.exe中的0x53072844(mfc140ud.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000020。

这有点奇怪的是,它上面的行不会导致访问冲突,尽管基本上是相同的。上面的一行是:

    ((CButton*)GetDlgItem( IDC_RADIO_VIEW1 ))->SetCheck( 1 );

有谁知道为什么会这样?

2 个答案:

答案 0 :(得分:3)

显然,标识为IDC_RADIO_VIEW1的项目存在,但标识为IDC_RADIO_VIEW2的项目不存在。因此,当您尝试检索该对话框项时,您将获得一个NULL指针。然而,您将其转换为CButton指针,然后尝试取消引用它而不验证指针。就在那里,你已经调用了未定义的行为。你的程序有一个严重的错误,任何事情都可能发生。幸运的是,在nasal demons被释放之前,运行时环境跳了进来并发出了访问冲突。

编写代码的正确方法是验证函数的返回值。如果没有别的,请使用断言:

CButton* pBtn = ((CButton*)GetDlgItem(IDC_RADIO_VIEW2));
ASSERT(pBtn != NULL);
pBtn->SetCheck(0);

这会给你一个非常易读(和可调试)的错误信息。

请注意,使用符号常量而不是幻数也会更具可读性。所以你应该写SetCheck(BST_UNCHECKED)(或BST CHECKEDBST_INDETERMINATE)。

答案 1 :(得分:0)

没有ID IDC_RADIO_VIEW2的控件作为您调用代码的对话框的直接子项。

未失败的代码行引用ID为IDC_RADIO_VIEW1的控件。按理说,对话框有一个标识为IDC_RADIO_VIEW1的直接子窗口。

我敢肯定,调用((CButton*)GetDlgItem( IDC_RADIO_VIEW999 ))->SetCheck( 1 );会出现完全不同的错误,尽管“基本上是相同的”。你真的需要学习计算机的工作原理。代码不起作用,因为它与其他工作代码类似(对于“类似”的某些定义)。

相关问题