从结构反序列化指针会给指针指针?



给定以下结构:

// 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

最新更新