我正在尝试访问我的一个MFC视图的对话框元素。为此,我运行以下代码行:
((CButton*)GetDlgItem( IDC_RADIO_VIEW2 ))->SetCheck( 0 );
这会导致以下异常:
在NameOfMyApplication.exe中的0x53072844(mfc140ud.dll)抛出异常:0xC0000005:访问冲突读取位置0x00000020。
这有点奇怪的是,它上面的行不会导致访问冲突,尽管基本上是相同的。上面的一行是:
((CButton*)GetDlgItem( IDC_RADIO_VIEW1 ))->SetCheck( 1 );
有谁知道为什么会这样?
答案 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 CHECKED
或BST_INDETERMINATE
)。
答案 1 :(得分:0)
没有ID IDC_RADIO_VIEW2
的控件作为您调用代码的对话框的直接子项。
未失败的代码行引用ID为IDC_RADIO_VIEW1
的控件。按理说,对话框有一个标识为IDC_RADIO_VIEW1
的直接子窗口。
我敢肯定,调用((CButton*)GetDlgItem( IDC_RADIO_VIEW999 ))->SetCheck( 1 );
会出现完全不同的错误,尽管“基本上是相同的”。你真的需要学习计算机的工作原理。代码不起作用,因为它与其他工作代码类似(对于“类似”的某些定义)。