C++ 从void中提取int*

C++ 从void中提取int*,c++,c++11,C++,C++11,我有一个方法返回void*,它基本上是linux上分配的共享内存中的一些数据块 数据中的前4个字节是一个int,我还没有设法提取这个int 以下是我尝试过的方法: int getNum(void* data) { return *(int*)data; // 1 return *(int*)(data & 0xFFFFFFFF); // 2 } 提前谢谢 int getNum(void* data) { return *(int32_t*)data; //

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

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

以下是我尝试过的方法:

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

int getNum(void* data) 
{
    return *(int32_t*)data; // 1
          // ^^^^^^^
} 
应该有用

此外,如果您需要担心从
void*
获得的未对齐地址,您可以使用:


假设int是4字节长的,并且您在Linux上操作,那么您的方法就可以工作了。如果您想要一个可移植的方法来移动指针中的int,请尝试CCAN中的开源模块。它通过将NULL添加到int来将指针转换为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
#包括
#包括
int getNum(无效*数据)
{
返回*(int*)数据;
}
char-buf[16];
内部主(空)
{
断言(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));
返回0;
}
//美元/富猫-电视
//^I^@^@^@
// 9
第二种方法甚至不会编译<代码>数据是指针,不能对指针值应用
&
按位and运算符。(我不知道你为什么会想这样屏蔽指针值。如果合法,屏蔽在32位系统上不会起任何作用,并且可能会破坏64位系统上的指针值。)

对于第一个,如果
data
是指向正确对齐的
int
对象的有效指针,那么它应该可以工作

如果在运行时由于分段错误而失败,则可能意味着
数据
为空或不是有效指针(在这种情况下,您无法执行您试图执行的操作),或者它指向未对齐的地址(如果您在x86或x86_64系统上,这不会导致seg故障;是吗?)

要了解指针的外观,请尝试添加以下内容:

printf("data = %p\n", data);
调用
getNum
函数,或者在调试器中检查
数据的值

如果存在对齐问题,则可以执行以下操作:

int result;
memcpy(&result, data, sizeof result);
return result;
但是在这种情况下,首先将
int
值存储为未对齐的地址是一件奇怪的事情。这不一定是错的,只是一件很奇怪的事情


数据所指向的内存是如何分配的?

数据的内容是什么?你得到的是什么?内容是一个int,然后是一个标志,是一个字节。。。我得到了一个分段错误问题是什么?@GioraGuttsait
(data&0xffffff)
屏蔽指针而不是数据本身。@πάντα:“
(data&0xffffff)
屏蔽指针而不是数据本身”`--不,它没有。它没有任何作用,因为
&
运算符不能应用于
void*
。谢谢,我一接触到工作站就会尝试一下。这与当前使用的有什么不同?对固定宽度的整数类型进行模化,即@Lightness是
int
被保证为32位固定的吗?我喜欢Martin Bonner关于对齐访问的观点。@KeithThompson“中的前4个字节…”要求来自源代码的4个字节。如果在提取后将其转换为普通的
int
,这对结果有影响吗?原则上,是的,可能会有影响。类型
int
可能有填充位。更现实地说,OP已经说过
返回*(int*)数据不起作用;用
int32\t
替换
int
不太可能改变这一点。屏蔽可能是要应用于结果值,我怀疑是输入错误。将
NULL
添加到
int
会将
int
转换为指针。但它很难携带;空指针上的指针算术具有未定义的行为。如果您确实需要将指针转换为整数,或者反之亦然,请使用强制转换。顺便说一句,您的
getNum
函数与问题中显示的第一个方法相同,OP已经说过该方法不起作用。是的,但是ptrint模块强制执行NULL,如下所示:return(ptrint_t*)((char*)NULL+i);我知道getNum与OP是相同的-我试图证明它确实有效,因此OP在其他地方可能有问题,例如值最初写入内存的位置。
printf("data = %p\n", data);
int result;
memcpy(&result, data, sizeof result);
return result;