最近我发现我的应用程序有一些奇怪的行为。它主要用 C# 开发,但也使用 CLI/C++ 来实现更好的性能。在 TimeSpan 比较中,我通过一个非常简单的方法得到了 System.NullReferenceException:
TimeSpan _timestamp;
void UpdateFrame(TimeSpan timestamp)
{
if(TimeSpan::Equals(_timestamp, timestamp) == false)
很明显,该表达式中使用的唯一引用是隐式的 this (this._timestamp)。我添加了一个assert语句,结果发现这实际上是null。经过简短的调查后,我设法准备了展示这一现象的短节目。它是 C++/CLI。
using namespace System;
using namespace System::Reflection;
public class Unmanaged
{
public:
int value;
};
public ref class Managed
{
public:
int value;
Unmanaged* GetUnmanaged()
{
SampleMethod();
return new Unmanaged();
}
void SampleMethod()
{
System::Diagnostics::Debug::Assert(this != nullptr);
this->value = 0;
}
};
public ref class ManagedAccessor
{
public:
property Managed^ m;
};
int main(array<System::String ^> ^args)
{
ManagedAccessor^ ma = gcnew ManagedAccessor();
// Confirm that ma->m == null
System::Diagnostics::Debug::Assert(ma->m == nullptr);
// Invoke method on the null reference
delete ma->m->GetUnmanaged();
return 0;
}
有谁知道这怎么可能?这是编译器中的错误吗?
在 C++ 中(大概在 C++/CLI 中),没有什么可以阻止您尝试调用 NULL 指针上的方法。在大多数实现中,虚拟方法调用将在调用时崩溃,因为运行时将无法读取虚拟方法表。然而,一个非虚拟的方法调用只是带有一些参数的函数调用,其中之一是this
指针。如果它为空,那么这就是传递给函数的内容。
我相信调用任何成员函数的结果NULL
(or nullptr
) 指针正式是“未定义的行为”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)