从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,当我这样做时,输出变成一个垃圾值。虽然我理解为什么它表现得像我不知道是否有解决方案。
如果你正在处理的问题真的与short
和int
有关,你可以简单地避开指针并使用:
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指针有一个特殊的例外,但它不适用于此处。
在您的示例中,short
和int
不是相关类型,因此,不允许通过指向另一个的指针访问它。
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的主要内容,如果未能解决你的问题,请参考以下文章