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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从void指针中获取一个指向short的int相关的知识,希望对你有一定的参考价值。

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

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

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

答案

如果你正在处理的问题真的与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*不是有效的操作所以不起作用。

另一答案

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

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

另一答案

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

   short n = 1;
   void* s = &n;
   int k = *(short*)s;  
另一答案

假设您有2个字节的短路和4个字节的整数,那么在您的方法中有三个问题。

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

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

最后,你有一个big-endian / little-endian依赖。你不能通过在最后添加一些0来将一个大端的短片变成一个小尾数。

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


正确的解决方案是使用原始类型并让编译器进行转换。而不是int k = *(int*)s;,你需要使用int k = *(short *)s;

以上是关于从void指针中获取一个指向short的int的主要内容,如果未能解决你的问题,请参考以下文章

使用指向 int 或 short int 的成员创建结构数组?

memcpy的用法总结

转:memcpy的用法总结

转: memcpy的用法总结

void型指针

void指针(void *的用法)