从void指针中获取一个指向short的int

时间:2017-12-18 21:15:44

标签: c++ pointers type-conversion void-pointers

我有一个来自库的返回值,它是一个void指针。我知道它指的是一个简短的int;我尝试以下列方式获取int值(用简单赋值替换函数调用void *):

short n = 1;
void* s = &n;
int k = *(int*)s;

我尝试转换一个指向一个地址的空指针,其中有一个短路,我尝试将指针转换为指向一个int,当我这样做时,输出变成一个垃圾值。虽然我理解为什么它表现得像我不知道是否有解决方案。

4 个答案:

答案 0 :(得分:6)

如果你正在处理的问题真的与shortint有关,你可以简单地避开指针并使用:

short n = 1;
int k = n;

如果您正在处理的对象类型不同,那么解决方案将取决于这些类型是什么。

更新,以回应OP的评论

在评论中,你说,

  

我有一个返回void指针的函数,我需要相应地转换值。

如果您知道该函数返回一个真正指向void*对象的short,那么,您最好的选择是:

 void* ptr = function_returning_ptr();
 short* sptr = reinterpret_cast<short*>(ptr);
 int k = *sptr;

*sptr评估为short后的最后一行工作,short转换为int是有效的操作。另一方面,

 int k = *(int*)sptr;

不起作用,因为将short*转换为int*不是有效的操作。

答案 1 :(得分:1)

您的代码受到未定义的行为影响,因为它违反了所谓的严格别名规则。在不进行太多细节和简化的情况下,规则规定除非类型X和Z相关,否则您无法通过指向Z类型的指针访问类型X的对象。 char指针有一个特殊的例外,但它不适用于此。

在您的示例中,shortint不是相关类型,因此,不允许通过指向另一个的指针访问。

答案 2 :(得分:0)

short的大小只有16位int的大小是32位(在大多数情况下并不总是)这意味着你欺骗计算机认为你的指针指向short实际上指向一个整数。这会导致它读取更多内存,并且正在读取垃圾内存。如果你将s转换为指向short的指针,那么它将起作用。

   short n = 1;
   void* s = &n;
   int k = *(short*)s;  

答案 3 :(得分:0)

假设你有2个字节的短路和4个字节的整数,那么在你的方法中有三个问题就是铸造指针。

首先,当使用短指针时,4字节int必然会拾取一些垃圾内存。如果您幸运short n之后的2个字节将为0。

其次,4字节int可能无法正确对齐。基本上,4字节int的内存地址必须是4的倍数,否则可能会导致总线错误。您的2字节short无法保证正确对齐。

最后,你有一个big-endian / little-endian依赖。你不能通过在最后添加一些0来将big-endian short变成little-endian int。

在非常幸运的情况下,short之后的字节为0,并且short是整数对齐的,并且系统使用小端表示,那么这样的强制转换可能会起作用。这将是可怕的,但它(可能)会起作用。

正确的解决方案是使用原始类型并让编译器强制转换。您需要使用int k = *(int*)s;

而不是int k = *(short *)s;