将short*强制转换为int*后读取值为何不符合预期?
为什么int指针读取short数组得到65536而非1?
你写的测试代码如下:
#include <stdio.h> #include <stdlib.h> #include <assert.h> int main() { short* p = (short*) malloc(2 * sizeof(short)); int* q = (int*) p; assert(sizeof *q == 2 * sizeof *p); p[0] = 0; p[1] = 1; printf("%u\n", *q); }
你预期*q输出1,但实际得到65536,核心原因是你的系统采用小端字节序:
- 小端字节序的规则是:多字节数据的低位字节存在内存低地址,高位字节存在内存高地址。
- 你分配的
short数组中,p[0](值0,占2字节)存在内存的低地址区域,p[1](值1,占2字节)存在高地址区域,对应内存的字节排布(从低到高)是:00 00 01 00 - 当用
int*指针读取这4字节时,小端序会把低地址的字节解析为int的低位部分,高地址的字节解析为高位部分,最终组合出的int值是0x00010000,转换成十进制就是65536。
如果是大端字节序的系统,才会按你预想的方式将字节组合成0x00000001(即1),但目前绝大多数x86/x86_64架构的系统都是小端序。
另外需要注意:这种将short*强制转换为int*后直接读取的行为,在C标准中属于未定义行为——因为指针指向的内存对象类型和指针本身的类型不匹配,标准不保证读取结果的确定性,只是在实际常见系统中会遵循字节序规则。
内容的提问来源于stack exchange,提问作者Raftel
相关产品推荐
相关产品推荐

