无符号的char数组转换为long long

时间:2014-01-10 15:49:49

标签: c++ casting unsigned-char long-long

我不确定这是否正确,我已经测试过,似乎有些字节已关闭... 基本上,我有以下内容:

unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
memcpy(szBuffer, (char*)&nValue, sizeof(long long));

//

long long nNewValue = reinterpret_cast<long long>(szBuffer);
printf(nNewValue); //prints out a smaller number than previously stated

有人会介意指出我哪里出错吗?谢谢。

3 个答案:

答案 0 :(得分:4)

您将nNewValue设置为szBuffer的地址,而不是从该地址读取数据。使用:

long long nNewValue = *reinterpret_cast<long long*>(szBuffer);

答案 1 :(得分:1)

更改此声明

long long nNewValue = reinterpret_cast<long long>(szBuffer);

long long nNewValue = *reinterpret_cast<long long *>(szBuffer);

答案 2 :(得分:0)

以下是您的程序的修改版本在我的系统上运行(扩展为完整的程序):

#include <iostream>
#include <cstring>
int main() {
    unsigned char szBuffer[1024] = {0};
    long long nValue = 1334553536;
    std::memcpy(szBuffer, &nValue, sizeof(long long));
    long long nNewValue = *(reinterpret_cast<long long*>(&szBuffer));
    std::cout << nValue << "\n" << nNewValue << "\n";
}

memcpy的前两个参数属于void*类型,因此您无需投射它们;如果你投了它们(是否在C ++中弃用了转换?),你应该转换为void*,而不是char*

nNewValue的分配将缓冲区的地址转换为long long*,然后取消引用转换后的值。

但这是一个坏主意。 g ++给出了关于转换指针的取消引用的警告:

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

此外,无法保证szBufferunsigned char数组)正确对齐,因此可以安全地将其前几个字节视为long long个对象。您最有可能使用的x86或x86_64系统容忍未对齐的内存访问,但并非所有系统都这样做。

指针演员通常不安全,除非你知道完全你正在做什么。

如果要将字符数组的一部分重新解释为某种其他类型的对象,则可以使用union,如果您确实需要将内存本身解释为不同类型的对象,或使用memcpy。 (即便如此,请确保您确实需要这样做;很可能您不这样做。大多数情况下,如果您想存储long long对象,您应该定义一个long long对象。)