int指针进入void指针然后进入双指针

时间:2014-01-24 10:09:50

标签: c void-pointers

#include <stdio.h>
#include <string.h>

main()
{
    int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 10;

printf("%d", sizeof(*double_ptr));

}

该程序的输出为8.
这是怎么回事? 我的意思是double_ptr指向4字节内存,但仍然输出为8 * 其他4个字节来自哪里???该程序应该崩溃,因为没有分配其他4个字节。 *
请解释一下??

3 个答案:

答案 0 :(得分:6)

C是静态类型,表达式sizeof *double_ptr仅根据这些静态类型规则计算,即double_ptr指向double,其大小为8

此程序具有未定义的行为,因为您正在写入您不会拥有的内存范围&#34;。所有赌注都已关闭,可能会崩溃或不崩溃。在进行这种讨厌的转换时,你应该对此负责,而不是编译器。

编辑,对于挑剔:

  • 符合规范的编译器不应容忍没有返回类型的函数。提高警告水平。
  • 在此处发布代码时,请正确缩进
  • sizeof运算符的结果不是int,而size_t是无符号类型。使用"%d"进行打印也具有未定义的行为。使用"%zu"

答案 1 :(得分:2)

  

我的意思是double_ptr指向4字节内存,但仍然输出为8。

这是因为sizeof是根据表达式的类型或类型进行评估的。此外,在这种情况下,无论指针的值如何,都可以在编译时对其进行全面评估。

  

*其他4个字节来自哪里???

它们属于与int位置相邻的内存区域。此区域未分配给您要写入的对象,因此它是未定义的行为。很有可能你正在写入指针本身,如果编译器在void_pointer之后立即将an_int放入内存中,就会发生这种情况。

  

该程序应该崩溃,因为其他4个字节没有分配给它。

不幸的是,并非所有未定义的行为都会导致崩溃。当无效程序没有崩溃时,这是C中的常见情况。例如,所有缓冲区溢出漏洞都依赖于程序在显示未定义的行为后不会崩溃的能力。

答案 2 :(得分:0)

sizeof是编译时运算符。所以它检查指针可能指向的数据类型(两个8字节),因此输出为8.

int main()
{
    int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 10;

printf("%d %d",*double_ptr,sizeof(*double_ptr));

} 
我已编辑了一下。它在尝试使用指针访问内存时崩溃。