bool,int或其他堆栈变量的NullReferenceException

时间:2015-01-14 13:48:24

标签: c++-cli nullreferenceexception

首先:这篇文章的标题与我的实际问题不符 但我也提供了原始问题的答案(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个函数,并在堆栈和堆上创建了几个变量......

1 个答案:

答案 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。