从void *

时间:2016-02-02 17:04:45

标签: c++ c++11

我有一个返回void*的方法,它基本上是来自linux上分配的共享内存的一些数据块。

该数据中的前4个字节是int,我还没有设法提取该int。

这些是我尝试过的方法:

int getNum(void* data) 
{
    return *(int*)data; // 1
    return *(int*)(data & 0xFFFFFFFF); // 2
} 

提前致谢!

3 个答案:

答案 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