使用 *(void**)this 检查虚函数 table
Checking virtual function table using *(void**)this
unreal engine源代码在有效性检查函数中有这个位:
if (*(void**)this == nullptr)
{
UE_LOG(LogUObjectBase, Error, TEXT("Virtual functions table is invalid."));
return false;
}
在这种情况下,this
是指向 class 的实例化对象的指针。我了解转换和取消引用在表面上的作用,但我不太清楚这如何帮助检查 vtable 是否有效。
这里有两个不同的问题:这段代码是做什么的,它有效吗?
实现虚表的一种常见方式是在对象的基址上存储指向虚表的指针。因此,例如,在 32 位机器上,对象的前四个字节将是指向 vtable 的指针,而在 64 位机器上,对象的前八个字节将是指向 vtable 的指针。
考虑到这一点,让我们考虑一下 *(void**)this
的作用。 this
指针指向对象的基址。我们想将该对象的开头解释为指向 vtable 的指针,因此我们想获取对象底部指针的值。然而,我们没有那个指针的名字,所以我们不能通过名字查找它,而且因为 vtable 是由编译器设置的,所以没有对应于“vtable”的 C++ 类型。因此,我们将执行以下操作。我们将把我们想要读取的指针设想为 void*
(指向“我们不知道其类型的东西”的指针)。this
指针正好指向 void*
,因此我们将引入一个 (void**)this
的转换来表示“假装 this
指向 void*
。”然后我们取消引用该指针以读取存储在那里的 void*
,这是我们的 vtable 指针。总的来说,这给了我们 *(void**)this
.
下一个问题是空检查为何有效。一般来说,这种安全检查是行不通的。它假定当为一个对象分配 space 时,在构造该对象之前将内存设置为全 0。假设是这种情况,如果尚未设置 vtable 指针,则分配给它的字节将为 0,这在某些 C++ 实现中被视为空指针。因此,您在此处列出的检查将读取 vtable 指针,查看它是否为空,如果为空则报告错误。
但是,这里有很多假设 - 在构造对象之前内存被清空,vtable 位于对象的确切基址等。我不熟悉的细节Unreal engine,但我认为它的设置可能是为了确保满足这些要求。
unreal engine源代码在有效性检查函数中有这个位:
if (*(void**)this == nullptr)
{
UE_LOG(LogUObjectBase, Error, TEXT("Virtual functions table is invalid."));
return false;
}
在这种情况下,this
是指向 class 的实例化对象的指针。我了解转换和取消引用在表面上的作用,但我不太清楚这如何帮助检查 vtable 是否有效。
这里有两个不同的问题:这段代码是做什么的,它有效吗?
实现虚表的一种常见方式是在对象的基址上存储指向虚表的指针。因此,例如,在 32 位机器上,对象的前四个字节将是指向 vtable 的指针,而在 64 位机器上,对象的前八个字节将是指向 vtable 的指针。
考虑到这一点,让我们考虑一下 *(void**)this
的作用。 this
指针指向对象的基址。我们想将该对象的开头解释为指向 vtable 的指针,因此我们想获取对象底部指针的值。然而,我们没有那个指针的名字,所以我们不能通过名字查找它,而且因为 vtable 是由编译器设置的,所以没有对应于“vtable”的 C++ 类型。因此,我们将执行以下操作。我们将把我们想要读取的指针设想为 void*
(指向“我们不知道其类型的东西”的指针)。this
指针正好指向 void*
,因此我们将引入一个 (void**)this
的转换来表示“假装 this
指向 void*
。”然后我们取消引用该指针以读取存储在那里的 void*
,这是我们的 vtable 指针。总的来说,这给了我们 *(void**)this
.
下一个问题是空检查为何有效。一般来说,这种安全检查是行不通的。它假定当为一个对象分配 space 时,在构造该对象之前将内存设置为全 0。假设是这种情况,如果尚未设置 vtable 指针,则分配给它的字节将为 0,这在某些 C++ 实现中被视为空指针。因此,您在此处列出的检查将读取 vtable 指针,查看它是否为空,如果为空则报告错误。
但是,这里有很多假设 - 在构造对象之前内存被清空,vtable 位于对象的确切基址等。我不熟悉的细节Unreal engine,但我认为它的设置可能是为了确保满足这些要求。