1

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

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

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

4

3 回答 3

4

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

long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
于 2014-01-10T16:00:00.047 回答
1

更改此声明

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

long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
于 2014-01-10T16:00:44.450 回答
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的前两个参数是 type void*,所以你不需要强制转换它们;如果您确实转换它们(C++ 中不推荐使用这种转换吗?),您应该转换为void*,而不是char*.

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

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

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

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

除非您确切知道自己在做什么,否则指针转换通常是不安全的。

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

于 2014-01-10T16:58:33.963 回答