1

我有0x48656c6c6f每个字节代表字符串中每个字符的 ASCII 值的十六进制值"Hello"。我还有一个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;
}

演示在这里。

4

4 回答 4

5

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

如果还有错误,ideone 确实会显示警告:http: //ideone.com/TSmDk5

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

于 2013-07-05T14:21:13.360 回答
5

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

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

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

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

于 2013-07-05T14:23:23.423 回答
1
int y = 0x48656c6c6f;

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

于 2013-07-05T14:22:34.077 回答
0

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

于 2013-07-05T14:24:04.297 回答