c++ - memcpy 将 ff ff ff 添加到一个字节的开头

标签 c++ memcpy

我有一个这样的数组:

unsigned char array[] = {'\xc0', '\x3f', '\x0e', '\x54', '\xe5', '\x20'};
unsigned char array2[6];

当我使用 memcpy 时:

memcpy(array2, array, 6);

然后打印它们:

printf("%x %x %x %x %x %x", array[0],  // ... etc
printf("%x %x %x %x %x %x", array2[0], // ... etc

打印如下:

c0 3f e 54 e5 20

但另一个打印

ffffffc0 3f e 54 ffffffe5 20

发生了什么事?

最佳答案

我已经将您的代码变成了一个完整的可编译示例。我还添加了第三个“普通”char 数组,它在我的环境中已签名。

#include <cstring>
#include <cstdio>

using std::memcpy;
using std::printf;

int main()
{

        unsigned char array[] = {'\xc0', '\x3f', '\x0e', '\x54', '\xe5', '\x20'};
        unsigned char array2[6];
        char array3[6];

        memcpy(array2, array, 6);
        memcpy(array3, array, 6);

        printf("%x %x %x %x %x %x\n", array[0], array[1], array[2], array[3], array[4], array[5]);
        printf("%x %x %x %x %x %x\n", array2[0], array2[1], array2[2], array2[3], array2[4], array2[5]);
        printf("%x %x %x %x %x %x\n", array3[0], array3[1], array3[2], array3[3], array3[4], array3[5]);

        return 0;
}

我的结果符合我的预期。

c0 3f e 54 e5 20
c0 3f e 54 e5 20
ffffffc0 3f e 54 ffffffe5 20

如您所见,只有当数组是有符号字符类型时,才会附加“额外”ff。原因是当 memcpy 填充带符号的 char 数组时,设置了高位的值现在对应负 char 值。当传递给 printf 时,char 被提升为 int 类型,这实际上意味着符号扩展。

%x 以十六进制打印它们,就好像它们是 unsigned int 一样,但是由于参数是作为 int 传递的,因此行为在技术上是未定义的.通常在二进制补码机上,行为与使用 mod 2^N 算术的标准有符号到无符号转换相同(其中 N 是 unsigned int 中的值位数)。由于该值只是“轻微”负数(来自窄带符号类型),转换后该值接近最大可能的 unsigned int 值,即它有许多前导 1 的(二进制)或十六进制的前导 f

关于c++ - memcpy 将 ff ff ff 添加到一个字节的开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3512749/

相关文章:

c++ - 设计模式中对象中过程(方法和操作)的状态

c++ - n 位有符号数,其中 n 不是 2 的幂

C malloc 和 memcpy 在拆分 char 数组时给出条件跳转 valgrind 错误

无法在C程序中拆分数组

从共享内存段复制数据会导致客户端出现段错误(信号量和共享内存)

c - 将 4 个字节复制到 float 时缓冲区溢出

c++ - 属性数组?

c++ - 空 OpenMP for 循环耗时 5 毫秒

c++ - 交叉编译器异常处理——可以安全地完成吗?

c - memcpy_ssse3 段错误