首先:这篇文章的标题与我的实际问题不符 但我也提供了原始问题的答案(bool上的NullRefExcp),因此其他用户将通过所选标题找到它的解决方案。
我有一个类,类似于以下内容:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
今天我遇到了func
在某些时候崩溃并出现NullReferenceException的问题,尽管之前已多次成功执行。
行if (!m_bInit)
中出现异常!
我知道,你们现在都说,这是不可能的。但实际上就是这条线。原因如下:
我有两个不同的变量,都命名为oTest,但在不同的地方。其中一个被初始化:oTest = gcnew CTest
。在这个oTest上调用func
效果很好。 func
对另一个oTest的第一次调用失败,但上述例外。奇怪的是,崩溃似乎发生在m_bInit
上的查询中,异常的堆栈跟踪也是如此。但这只是第一个调用未初始化对象(它仍然是nullptr)的成员的地方。
因此,对具有相同问题的其他用户的建议:向后检查堆栈以查找对象为nullptr / null的函数调用。
我现在的问题是:
为什么在第一次调用oTest函数时执行没有失败,这是nullptr?
为什么在第一次访问成员之前输入并执行该功能?
实际上,在我的情况下,输入了3个函数,并在堆栈和堆上创建了几个变量......
答案 0 :(得分:3)
此代码:
void func()
{
if (!m_bInit)
return;
...
}
实际上可以写成:
void func()
{
if (!this->m_bInit)
return;
...
}
希望现在你可以看到问题的来源。
成员函数调用只是一个常规函数调用,它隐式包含this
参数(它与其他参数一起传递)。
C ++ / CLI编译器在调用非虚函数时不会执行nullptr
检查 - 它会发出call
MSIL opcode。
在C#中实际情况并非如此,因为C#编译器即使对于非虚函数也会发出callvirt
MSIL opcode。此操作码强制JIT对目标实例执行null
检查。在C#中获得此错误的唯一方法是通过反射调用函数或生成使用call
操作码的IL。