C ++得到了指针而不是值

时间:2014-03-24 13:10:35

标签: c++

我想知道为什么指针值(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); 
}

1 个答案:

答案 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 ++中,这不是解码二进制数据的安全方法。