这通常很危险:
*((unsigned int*)myData)
Intel IA-32(每个人都习惯)支持非对齐访问,但其他一些架构不支持。它们要求变量对齐(1 字节边界上的 8 位数据、2 字节边界上的 16 位数据和 4 字节边界上的 32 位数据)。在需要对齐的架构上,未对齐的访问将返回损坏的数据或引发 CPU 异常。我在过去的工作中看到它在现实生活中导致了一个错误,一个微妙的错误导致文件系统损坏,因为我们使用的软件包附带的磁盘驱动程序(在嵌入式平台上)。
在这种孤立的情况下,您可以看到 myData 的地址来自 malloc(),这应该意味着它适合所有类型的指针对齐,但是如果您不这样做,将较小的指针转换为较大的指针通常是一种危险的做法'不知道指针是从哪里来的。
从任意内存位置提取 32 位整数的安全方法是声明一个临时 32 位整数并对其执行复制,将源内存视为原始字符数组:
unsigned int GetUnalignedLittleEndianUInt32(void *address)
{
unsigned char *uc_address = (unsigned char *)address;
return (
(uc_address[3] << 24) |
(uc_address[2] << 16) |
(uc_address[1] << 8) |
uc_address[0]
);
}
或更一般地说(有一些函数调用开销):
unsigned int GetUnalignedUInt32(void *address)
{
unsigned int value;
memcpy(&value, address, sizeof(value));
return value;
}
这实际上与你最初为获取指针所做的 memcpy() 操作相反。
虽然,将指针视为 int:
int addressOfArgTwo = (unsigned int)buff;
正如迈克尔指出的那样,如果您在 32 位和 64 位架构之间移动,这也是危险的。指针并不总是 32 位整数。考虑使用稍后可以更改的 typedef。 Linux 上的约定是指针与 long 大小相同。在 Windows 上,有类型定义 INT_PTR、UINT_PTR、LONG_PTR 和 ULONG_PTR。
所以,我最后建议(无论如何在 Windows 上):
ULONG_PTR GetAddressAtAddress(void *address)
{
ULONG_PTR value;
memcpy(&value, address, sizeof(value));
return value;
}