码迷,mamicode.com
首页 > 编程语言 > 详细

C语言printf()函数详解和安全隐患

时间:2015-08-12 19:39:45      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

一、问题描述

      技术分享

 

二、进一步说明

      请仔细注意看,有如下奇怪的现象

     

   int a=5;
        floatx=a;     //这里转换是没有问题的,%f打印x是 5.000000
       
        printf("%d\n",a);  
        printf("%f\n",a);  //输出为什么是0.000000? -----问题1
        printf("%f\n",x);
        printf("%d\n",x);  //输出为什么是0?        -----问题2
        printf("%f,%f\n",a,x);  //输出都是0.000000  为什么?            ----问题3
        printf("%f,%f\n",x,a);  //调换一下a,x的顺序,正常了,为什么?  ----问题4
        printf("%d,%f\n",a,x);
 
        getchar();
        return0;


三、printf()函数的原理解释

      明白这些问题首先需要明白printf()函数的工作原理。

 

     printf()维持了一个需要打印的变量栈,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:

      

                                                                  技术分享

      打印的时候,printf按照字符转换说明符规定的格式从低地址开始提取数据,直到参数打印完。

 

      比如遇到 %f 说明符就提取8个字节的数据,遇到 %d 就提取4个字节。看到这里,你也许会问一个问题,如果后面的字节数不够了怎么办?

   

      恭喜你,你发现了printf()的安全隐患,没错,它会强行读取临近内存的数据当作正常数据输出————很有可能产生堆溢出!

     

比如这样的代码:

    char string[]="Hello World!";
    printf("String: %s  ,强行再读一次: %#p , 再读一次: %#p\n", string);

输出如下: 

    String:Hello World!  , 强行再读一次: 0X001C1073 , 再读一次: 0X001C1073

 


三、问题解释

(1) 问题1:printf("%f\n",a) 输出为什么是0.000000?

答:%f 提取8字节,a只有4字节,提取出来的数占了float表示法的指数部分,尾数部分为0,所以最终是0

 

(2) 问题2:printf("%d\n",x)  输出为什么是0?

答:%d 提取4字节,x有8字节,提取出来的数实际上是float表示法的指数部分(恰好是0),所以最终是0

 

(3) 问题3:printf("%f,%f\n",a,x); 输出都是0.000000 为什么?

答:参照问题1的解释,提取了八字节后,后面的已经乱了

(4) 问题4:printf("%f,%f\n",x,a);调换一下a,x的顺序,正常了,为什么?

答:这是正常的情况而已。

 

 

 

 

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

C语言printf()函数详解和安全隐患

标签:

原文地址:http://blog.csdn.net/a369414641/article/details/47447193

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!