Linux 和 Windows 的输出差异

Output difference on Linux and Windows

unsigned long id = 12;
unsigned long age = 14;
unsigned char* pData = new unsigned char[8];
memcpy(pData,&id,4);/* using memcpy to copy */
pData = pData + 4;
memcpy(pData,&age,4);/* using memcpy to copy */
std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;
pData = pData - 4;
std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

输出 linux

14 60129542156

在 windows (vc++)

14 12

您假设 sizeof(unsigned long) 始终为 4。这是不正确的。

试试这个:

const size_t NBYTES = sizeof(unsigned long);
unsigned long id = 12;
unsigned long age = 14;
unsigned char* pData = new unsigned char[2 * NBYTES];
memcpy(pData,&id, NBYTES);/* using memcpy to copy */
pData = pData + NBYTES;
memcpy(pData,&age, NBYTES);/* using memcpy to copy */
std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;
pData = pData - NBYTES;
std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

如果要使用显式数据大小,请使用 <cstdint> 中定义的类型。可以找到文档 here.

memcpy(pData,&id,4);/* using memcpy to copy */
//               ^

您假设 sizeof (unsigned long)4 这在系统上可能是也可能不是,因为它取决于实现。

使用以下行以获得一致的行为。

memcpy(pData,&id,sizeof id);/* using memcpy to copy */

此外,如果某天变量的大小超过 8,则以下行可能会导致问题。将这些也更改为 sizeof

unsigned char* pData = new unsigned char[2 * sizeof (unsigned long)];
...
pData = pData + sizeof id;  // etc

在 Windows 上,主要是出于向后兼容的原因,即使在 64 位上,sizeof(long) 也是 4。在 x86-64(您可能使用的平台)中的 linux sizeof(long) 是 8 个字节。

在您的程序中使用 sizeof() 而不是 4。

unsigned long 如果您使用不同的操作系统,则大小不同。

在32位机器上,通常unsigned long是32位(4字节)。
在 64 位上,通常 unsigned long 是 64 位(8 字节)。

最重要的是,这取决于什么是 C/C++ 编译器。例如。某些编译器适用的情况可能不适用于其他编译器。

最后我没看到你在哪里释放你用 new 分配的内存。

这是您使用 sizeof() 的代码:

#include <iostream>

#include <string.h>

int main(){
    unsigned long id = 12;
    unsigned long age = 14;
    size_t size = sizeof(unsigned long);
    unsigned char* pData = new unsigned char[2*size];

    memcpy(pData, &id, size);/* using memcpy to copy */

    pData = pData + size;

    memcpy(pData, &age, size);/* using memcpy to copy */

    std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

    pData = pData - size;

    std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

    // do you need to release the dynamic memory?
    delete pData;

    return 0;
}

希望这对您有所帮助。如果我遗漏了什么,请发表评论。

更新:

我好像没看懂代码。我更新了代码。

我会为您提供使用指针算法的更新版本:

#include <iostream>

#include <string.h>

int main(){
    unsigned long id = 12;
    unsigned long age = 14;

    unsigned long* pData = new unsigned long[2];

    memcpy(pData, &id, sizeof(unsigned long));/* using memcpy to copy */

    pData++;

    memcpy(pData, &age, sizeof(unsigned long));/* using memcpy to copy */

    std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

    pData--;

    std::cout<<*reinterpret_cast<unsigned long*>(pData)<<std::endl;

    // do you need to release the dynamic memory?
    delete pData;

    return 0;
}

如果我是你,我会这样做 - 例如没有 sizeof,没有 & (address of).

#include <iostream>

#include <string.h>

int main(){
    unsigned long id = 12;
    unsigned long age = 14;

    unsigned long *pData = new unsigned long[2];

    pData[0] = id;
    pData[1] = age;

    std::cout << pData[1] << std::endl;

    std::cout << pData[0] << std::endl;

    delete pData;

    return 0;
}

希望这对您有所帮助。如果我遗漏了什么,请发表评论。

我看到了 Windows / Microsoft C++ 和 unsigned long 大小的注释。这可能是真的,但我仍然认为 sizeof() 是做到这一点的方法。使用 sizeof() 代码可移植性更强,可以编译到不同的平台,即使在您不了解的平台上也是如此。