bool、int 或其他堆栈变量的 NullReferenceException
NullReferenceException on bool, int, or other stack variable
首先:这个post的标题与我的实际问题不符。
但我也提供了原始问题的答案(bool 上的 NullRefExcp),因此其他用户将通过所选标题在这里找到它的解决方案。
我有一个class,类似下面的:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
今天我遇到了 func
虽然之前已经成功执行了很多次,但在某个时候崩溃并出现 NullReferenceException 的问题。
异常发生在行 if (!m_bInit)
!
我知道,你们现在都在说,这是不可能的。但它实际上是这条线。原因如下:
我有两个不同的变量,都命名为 oTest,但位于不同的位置。其中之一已初始化:oTest = gcnew CTest
。在此 oTest 上调用 func
效果很好。对另一个 oTest 的 func
的第一次调用失败,但出现上述异常。奇怪的是,崩溃似乎发生在 m_bInit
的查询中,异常的堆栈跟踪也说明了这一点。但这只是第一个调用未初始化 object 成员(它仍然是 nullptr)的地方。
因此,对其他有相同问题的用户的建议:向后检查堆栈以找到 object 上的函数调用,即 nullptr/null.
我现在的问题是:
为什么在第一次调用 nullptr 的 oTest 函数时执行不会失败?
为什么直到第一次访问某个成员才进入并执行该功能?
实际上,在我的例子中,输入了 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。
首先:这个post的标题与我的实际问题不符。
但我也提供了原始问题的答案(bool 上的 NullRefExcp),因此其他用户将通过所选标题在这里找到它的解决方案。
我有一个class,类似下面的:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
今天我遇到了 func
虽然之前已经成功执行了很多次,但在某个时候崩溃并出现 NullReferenceException 的问题。
异常发生在行 if (!m_bInit)
!
我知道,你们现在都在说,这是不可能的。但它实际上是这条线。原因如下:
我有两个不同的变量,都命名为 oTest,但位于不同的位置。其中之一已初始化:oTest = gcnew CTest
。在此 oTest 上调用 func
效果很好。对另一个 oTest 的 func
的第一次调用失败,但出现上述异常。奇怪的是,崩溃似乎发生在 m_bInit
的查询中,异常的堆栈跟踪也说明了这一点。但这只是第一个调用未初始化 object 成员(它仍然是 nullptr)的地方。
因此,对其他有相同问题的用户的建议:向后检查堆栈以找到 object 上的函数调用,即 nullptr/null.
我现在的问题是:
为什么在第一次调用 nullptr 的 oTest 函数时执行不会失败?
为什么直到第一次访问某个成员才进入并执行该功能?
实际上,在我的例子中,输入了 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。