我有一个返回void*
的方法,它基本上是来自linux上分配的共享内存的一些数据块。
该数据中的前4个字节是int
,我还没有设法提取该int。
这些是我尝试过的方法:
int getNum(void* data)
{
return *(int*)data; // 1
return *(int*)(data & 0xFFFFFFFF); // 2
}
提前致谢!
答案 0 :(得分:2)
int getNum(void* data)
{
return *(int32_t*)data; // 1
// ^^^^^^^
}
应该工作。
此外,如果您需要担心从void*
获得的未对齐地址,您可以使用@Martin Bonner's suggestion:
int getNum(void* data)
{
int32_t result;
memcpy(&result, data, sizeof(int32_t));
return result;
}
答案 1 :(得分:1)
int getNum(void* data)
{
return *(int*)data; // 1
return *(int*)(data & 0xFFFFFFFF); // 2
}
第二种方法甚至不能编译; data
是一个指针,您不能将&
按位和运算符应用于指针值。 (我不知道为什么你甚至想要屏蔽这样的指针值。如果它是合法的,那么掩码在32位系统上什么都不做,并且可能会破坏指针上的指针值。 64位系统。)
至于第一个,它应该有效 - 如果 data
是指向正确对齐的int
对象的有效指针。
如果在运行时因分段错误而失败,则可能意味着data
为空或者不是有效指针(在这种情况下,可以&#39; t < / em>做你正在尝试做的事情),或者它指向一个未对齐的地址(如果你是在x86或x86_64系统上,它不会导致seg故障;你呢?)
要找出指针的外观,请尝试添加:
printf("data = %p\n", data);
到getNum
函数 - 或者在调试器中检查data
的值。
如果对齐是问题,那么你可以这样做:
int result;
memcpy(&result, data, sizeof result);
return result;
但在这种情况下,将int
值存储为未对齐的地址首先是一件奇怪的事情。它不一定是错的,只是一件非常奇怪的事情。
data
分配的内存如何分配?
答案 2 :(得分:0)
假设int长度为4个字节,并且您在Linux上运行,那么您的方法将起作用。如果您希望便携式方法在指针中移动ints,请尝试CCAN中的开源ptrint模块。它通过向int添加NULL将指针转换为int。它通过减去NULL来转换另一个方向,返回一个ptrdiff_t。
#include <assert.h>
#include <stdio.h>
int getNum(void* data)
{
return *(int *) data;
}
char buf[16];
int main(void)
{
assert(sizeof(int) == 4);
*(int *)buf = 9;
printf("%c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
printf("%d\n", getNum((void *) buf));
return 0;
}
// $ ./foo | cat -tv
// ^I^@^@^@
// 9