从指向 short 的 void 指针获取 int
Obtaining an int from a void pointer which points to a short
我有一个来自库的 return 值,它是一个空指针。我知道它指向一个 short int;我尝试通过以下方式获取 int 值(用对 void *
的简单赋值替换函数调用):
short n = 1;
void* s = &n;
int k = *(int*)s;
我尝试转换一个指向一个地址的空指针,其中有一个 short,我尝试将指针转换为指向一个 int,当我这样做时,输出变成了一个垃圾值。虽然我明白为什么会这样,但我不知道是否有解决方案。
short 的大小只有 16 位而 int 的大小是 32 位(在大多数情况下并非总是如此)这意味着您在欺骗计算机认为您指向 short 的指针实际上指向一个整数。这导致它读取更多它应该读取的内存并且正在读取垃圾内存。如果您将 s 转换为指向 short 的指针,然后对其进行引用,它将起作用。
short n = 1;
void* s = &n;
int k = *(short*)s;
如果您正在处理的问题确实涉及 short
和 int
,您可以简单地避开指针并使用:
short n = 1;
int k = n;
如果您处理的对象类型不同,则解决方案将取决于这些类型。
更新,回应OP的评论
在评论中,您说,
I have a function that returns a void pointer and I would need to cast the value accordingly.
如果您知道 returns 函数 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*
不是有效操作。
您的代码存在未定义行为,因为它违反了所谓的严格别名规则。没有过多的细节和简化,该规则声明您不能通过指向类型 Z 的指针访问类型 X 的对象,除非类型 X 和 Z 相关。 char指针有一个特殊的例外,但它不适用于这里。
在您的示例中,short
和 int
不是相关类型,因此,不允许通过指向另一个的指针访问一个。
假设您有 2 个字节的短整型和 4 个字节的整数,在您的方法中转换指针有 3 个问题。
首先,当使用 short 的指针时,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 = *(short *)s;
而不是 int k = *(int*)s;
我有一个来自库的 return 值,它是一个空指针。我知道它指向一个 short int;我尝试通过以下方式获取 int 值(用对 void *
的简单赋值替换函数调用):
short n = 1;
void* s = &n;
int k = *(int*)s;
我尝试转换一个指向一个地址的空指针,其中有一个 short,我尝试将指针转换为指向一个 int,当我这样做时,输出变成了一个垃圾值。虽然我明白为什么会这样,但我不知道是否有解决方案。
short 的大小只有 16 位而 int 的大小是 32 位(在大多数情况下并非总是如此)这意味着您在欺骗计算机认为您指向 short 的指针实际上指向一个整数。这导致它读取更多它应该读取的内存并且正在读取垃圾内存。如果您将 s 转换为指向 short 的指针,然后对其进行引用,它将起作用。
short n = 1;
void* s = &n;
int k = *(short*)s;
如果您正在处理的问题确实涉及 short
和 int
,您可以简单地避开指针并使用:
short n = 1;
int k = n;
如果您处理的对象类型不同,则解决方案将取决于这些类型。
更新,回应OP的评论
在评论中,您说,
I have a function that returns a void pointer and I would need to cast the value accordingly.
如果您知道 returns 函数 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*
不是有效操作。
您的代码存在未定义行为,因为它违反了所谓的严格别名规则。没有过多的细节和简化,该规则声明您不能通过指向类型 Z 的指针访问类型 X 的对象,除非类型 X 和 Z 相关。 char指针有一个特殊的例外,但它不适用于这里。
在您的示例中,short
和 int
不是相关类型,因此,不允许通过指向另一个的指针访问一个。
假设您有 2 个字节的短整型和 4 个字节的整数,在您的方法中转换指针有 3 个问题。
首先,当使用 short 的指针时,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 = *(short *)s;
int k = *(int*)s;