为何memcpy后数据字节顺序反转?大小端与memcpy作用解析
问题:memcpy后每个字的内容被反转
我理解大小端(endianness)概念,也查阅过相关帖子,但仍无法解释当前现象:
我将数据存入unsigned char类型数组,原本认为memcpy是大小端无关的,数据的最左位应保持在最左,但打印时发现每个字(word)的内容都被反转了。
测试代码
#include <iostream> #include <cstring> #include <array> const unsigned int MAX_VALUE = 64ul; typedef unsigned char DDS_Octet[MAX_VALUE]; int main() { // 创建数组并填充可打印字符 DDS_Octet octet; for(int i = 0; i < MAX_VALUE; ++i) octet[i] = (i + 33); // 打印memcpy前的字符 for(int i = 0; i < MAX_VALUE; ++i) { if(i && !(i % 4)) std::cout << "\n"; std::cout << octet[i] << "\t"; } std::cout << "\n\n------------------------------\n"; // 模拟实际使用的复制操作 std::array<unsigned int, 16> arr; memcpy( arr.data(), octet, sizeof(octet)); // 按从左到右(小端系统上的MSB到LSB)打印每个字的字符内容 for(auto i : arr) std::cout << (char)(i >> 24) << "\t" << (char)((i >> 16) & 0xFF) << "\t" << (char)((i >> 8) & 0xFF) << "\t" << (char)(i & 0xFF) << "\n"; }
输出结果
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` ------------------------------ $ # " ! ( ' & % , + * ) 0 / . - 4 3 2 1 8 7 6 5 < ; : 9 @ ? > = D C B A H G F E L K J I P O N M T S R Q X W V U \ [ Z Y ` _ ^ ]
原因解析(更新)
查看memcpy的源码后,终于理清了原因:整数的大小端存储是根本原因,结合memcpy的逐字节复制机制,共同导致了字节顺序反转。
此前忽略了memcpy是按字节顺序复制的——它会把源地址的字节从低到高依次复制到目标地址。而在小端系统中,unsigned int类型的整数会将最低有效字节(LSB)存储在内存的最低地址,最高有效字节(MSB)存储在最高地址。
比如原数组中前4个字节是!(0x21)、"(0x22)、#(0x23)、$(0x24),memcpy会把它们依次复制到unsigned int的内存地址中:
- 0x21 存入整数的最低地址(对应LSB)
- 0x22 存入次低地址
- 0x23 存入次高地址
- 0x24 存入最高地址(对应MSB)
当我们通过右移操作打印时(i >>24取MSB,i&0xFF取LSB),就会得到$、#、"、!的反转结果。
memcpy源码
void * memcpy (void *dest, const void *src, size_t len) { char *d = dest; const char *s = src; while (len--) *d++ = *s++; return dest; }
内容的提问来源于stack exchange,提问作者mreff555
相关产品推荐
相关产品推荐

