2014-01-24 128 views
2
#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个字节未分配给它。 *
请解释??int指针变为void指针,然后变成双指针

+0

旁注:打印“size_t”类型的值时应使用'%zu'。 – user694733

回答

6

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

该程序有未定义的行为,因为您正在写入一个您不属于“拥有”的内存范围。所有投注都关闭,它可能会崩溃或不崩溃。当你做这样的恶意转换时,你是负责的,而不是编译器。

编辑,为挑剔:无返回值类型

  • 功能不应该由一个符合标准的编译是不能容忍的。提高警戒级别。
  • 张贴在这里的代码时,请缩进它sizeof运营商的正常
  • 结果不intsize_t无符号类型。打印与"%d"也有未定义的行为。使用"%zu"
2

我的意思是double_ptr指着4个字节存储器,但仍然输出是8

这是因为sizeof是基于类型或表达式的类型进行评价。而且,在这种情况下,无论指针的值如何,它都可以在编译时进行全面评估。

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

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

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

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

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)); 

} 

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