这不是跨平台代码......所有内容都在同一平台上执行(即endianess是相同的..小端)。
我有这段代码:
unsigned char array[4] = {'t', 'e', 's', 't'};
unsigned int out = ((array[0]<<24)|(array[1]<<16)|(array[2]<<8)|(array[3]));
std::cout << out << std::endl;
unsigned char buff[4];
memcpy(buff, &out, sizeof(unsigned int));
std::cout << buff << std::endl;
我希望buff的输出是“test”(由于缺少'/ 0'而带有垃圾尾随字符),而输出是“tset”。显然改变我正在移动的字符顺序(3,2,1,0而不是0,1,2,3)解决了问题,但我不明白这个问题。 memcpy不按照我的预期行事吗?
感谢。
答案 0 :(得分:9)
这是因为你的CPU是little-endian。在内存中,数组存储为:
+----+----+----+----+
array | 74 | 65 | 73 | 74 |
+----+----+----+----+
用增加字节地址表示 right 。但是,整数存储在内存中,左侧是最小有效字节:
+----+----+----+----+
out | 74 | 73 | 65 | 74 |
+----+----+----+----+
这恰好代表整数0x74657374。使用memcpy()
将其复制到buff
会反转原始array
中的字节。
答案 1 :(得分:2)
你是在一个小端平台上运行它。
在little-endian平台上,32位int存储在内存中,最低内存地址中的最低有效字节。因此,位0-7存储在地址P,位8-15存储在地址P + 1中,位16-23存储在地址P + 2中,位24-31存储在地址P + 3中。
在您的示例中:位0-7 ='t',位8-15 ='s',位16-23 ='e',位24-31 ='t'
这就是字节写入内存的顺序:“tset”
如果你将内存作为单独的字节(无符号字符)寻址,你将按它们写入内存的顺序读取它们。
答案 2 :(得分:0)
在little-endian平台上,输出应为tset
。从较低地址到较高地址的原始序列为test
。然后你将它放入unsigned int
,第一个't'进入最重要的字节,最后一个't'进入最低有效字节。在小端机器上,最低有效字节存储在较低地址。这是将它复制到最终buf
的方式。这是它的输出方式:从最后的't'到第一个't',即tset
。
在大端机器上你不会观察到逆转。
答案 3 :(得分:0)
如何向'\0'
添加buff
?
答案 4 :(得分:0)
您已经为平台字节顺序编写了测试,并得出结论: little endian 。