我想知道为什么指针值(324502)在var signalLengthDebugVar1中而不是预期的整数值(2)?
struct ShmLengthOfSignalName {
int signalLength;
};
//...
BYTE* pBuf = NULL;
//...
int main(void){
//...
pBuf = (BYTE*) MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
//...
JobaSignal sig1;
printf("Value SignalLength: %d \r\n", pBuf[30]); // 2
const ShmLengthOfSignalName * signalNameLengthPtr = (const ShmLengthOfSignalName *)(pBuf + 30);
int signalLengthDebugVar1 = signalNameLengthPtr->signalLength; // content: 324502 maybe pointer?
int signalLengthDebugVar2 = (int) pBuf[30]; // content 2
sig1.setNameLength(signalLengthDebugVar2);
}
答案 0 :(得分:3)
当您打印该值时,您只能在pBuf + 30
处读取单个字节:
// takes pBuf[30], converts that byte's value to int, and prints it
printf("Value SignalLength: %d \r\n", pBuf[30]); // 2
稍后,当您转换指针并取消引用它时,您将访问一个完整的int ,即sizeof(int)
个字节(可能是4个)。这不仅会占用pBuf + 30
处的字节,还会占用pBuf + 31
上的后续字节等,最高可达平台上的sizeof(int)
。它还根据平台的字节字节顺序解释这些字节(英特尔的小端,大多数其他平台的大端)。
// the signalLength struct member is an int
int signalLengthDebugVar1 = signalNameLengthPtr->signalLength; // content: 324502 maybe pointer?
另请注意,允许编译器在其signalLength
字段的位置之前或之后添加填充。换句话说,除非使用signalLength
或编译器特定的extern "C"
,否则不能假设#pragma
将从struct offset零开始。即使这样,你也无法控制字节序解释,所以如果数据被编码为big-endian并且你在像x86这样的小端机器上,那么你看到的价值就是错误的。
最重要的是,在C ++中,这不是解码二进制数据的安全方法。