给定以下结构:
// sizeof == 8
struct Data {
int Foo;
int Bar;
};
// sizeof == 16
struct __declspec(align(8)) Consumer {
char Padder00[4];
char Padder01[4];
Data* Data;
};
我希望Data*
等于一个数字,跨越 8 个字节(因为我在 x64 上),这是类型Data
结构的起始地址。
现在,对以下示例进行解散:
int main()
{
Consumer consumer;
consumer.Data = (Data*)malloc(sizeof(Data));
// consumer.Data == 0x0000013c86eb1300
// &consumer.Data == 0x00000037cdcff660
consumer.Data->Bar = 1337;
consumer.Data->Foo = 42069;
char* stepper = (char*)(&consumer);
stepper += 4; // skipping 1st padder
stepper += 4; // skipping 2nd padder
Data* restored = ((Data*)stepper);
// restored == 0x00000037cdcff660
// == &consumer.Data
free(consumer.Data);
std::getchar();
return 0;
}
所以restored == &consumer.Data
虽然我希望它是restored == consumer.Data
,但更进一步并查看stepper
的每个字节会产生以下内容:
stepper[0] = 0x00
stepper[1] = 0x13
stepper[2] = 0xeb
stepper[3] = 0x86
stepper[4] = 0x3c
stepper[5] = 0x01
stepper[6] = 0x00
stepper[7] = 0x00
// 0x0000013c86eb1300 (little endian)
// 0x0000013c86eb1300 == consumer.Data
总结:
((Data*)stepper) == &consumer.Data == (*(Data**)stepper)
我期望它在哪里
((Data*)stepper) == consumer.Data
那么......这里到底发生了什么巫术?
错误是这一行
Data* restored = ((Data*)stepper);
它应该是
Data* restored = *((Data**)stepper);
stepper
指向Data
(字段)所在的位置,该位置本身就是一个指针。因此,取消引用stepper
会为您提供Data
指针,您需要取消引用它才能获得Data
。