为什么从int到char的memcpy不起作用

Why is memcpy from int to char not working?

本文关键字:memcpy 不起作用 char int 为什么      更新时间:2023-10-16

我有十六进制值0x48656c6c6f,其中每个字节表示字符串"Hello"中每个字符的ASCII值。我还有一个char数组,我想将这些值插入其中。

当我有一个较小的十六进制值(例如,0x48656c6c,它表示"Hell")时,打印出char数组会得到正确的输出。但是下面的代码打印"olle"(以小端序),但不打印"olleH"。为什么会这样?

#include <iostream>                           
#include <cstring>                             
int main()
{
    char x[6] = {0};
    int y = 0x48656c6c6f;
    std::memcpy(x, &y, sizeof y);
    for (char c : x)
        std::cout << c;
}

演示在这里。

在您的机器上,int可能是32位,这意味着您的常量的高位字节被截断;所以,您的int y = 0x48656c6c6f;实际上是int y = 0x656c6c6f;(顺便说一句,我认为它算作有符号整数溢出,因此是未定义的行为;要在这里定义行为,应该使用unsigned int)。

因此,在一个小endian机器上,y在内存中的表示是6f 6c 6c 65,它被复制到x,从而产生您看到的"olle"。

要"解决"这个问题,您应该使用一个更大的整数,根据您的平台,它可能是long longint64_t或类似的东西。在这种情况下,请确保使x足够大(char x[sizeof(y)+1]={0})以避免缓冲区溢出,或者将memcpy更改为仅复制适合x的字节。

此外,在执行这些技巧时,请始终使用unsigned整数——您可以避免UB,并在溢出的情况下获得可预测的行为。

int在您的平台上可能是四个字节。

如果同时存在错误,ideone确实会显示警告:http://ideone.com/TSmDk5

prog.cpp:在函数"int main()"中:prog.cpp:7:13:警告:隐式常量转换中溢出[-Woverflow]prog.cpp:12:5:错误:未在此作用域中声明"error"

int y = 0x48656c6c6f;

int不能保证存储它,可能是因为您的机器是32位的。使用long long代替

这是因为在您的平台上,int只有4个字节,而当您提供大于该值的文字时,H将被截断。