C语言printf()函数具体解释和安全隐患
一、问题描写叙述
二、进一步说明
请细致注意看,有例如以下奇怪的现象
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()事实上不知道參数的个数,它仅仅会依据format中的打印格式的数目依次打印堆栈中參数format后面地址的内容。
这样一来,printf()事实上存在安全隐患——没错,它会强行读取内存的数据当作正常数据输出,没有边界检測————非常有可能产生堆溢出!
比方这种代码:
char string[]="Hello World!";
printf("String: %s ,强行再读一次: %#p\n", string);
printf("String: %s ,强行再读一次: %#s\n", string);
输出例如以下:
String:Hello World! , 强行再读一次: 0X001C1073
String: Hello World! ,强行再读一次: 閮
三、问题解释
(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()函数具体解释和安全隐患的更多相关文章
- C语言printf()函数:格式化输出函数
C语言printf()函数:格式化输出函数 头文件:#include <stdio.h> printf()函数是最常用的格式化输出函数,其原型为: int printf( char ...
- C语言printf函数转换说明表及其修饰符表
请求printf()函数打印数据的指令要与打印数据的类型匹配. 例如, 打印整数时使用%d, 打印字符是使用%c. 这些符号被称为转换说明, 他们指定了数据转换称可显示的形式. 1. ANSI C标准 ...
- C语言scanf函数详细解释
原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...
- C语言scanf函数详细解释(转载)
原文地址:https://blog.csdn.net/21aspnet/article/details/174326 scanf 函数名: scanf 功 能: 执行格式化输入 用 法: int sc ...
- C语言 Printf函数
#include <stdio.h> int main(int argc, const char * argv[]) { // insert code here... printf(&qu ...
- C语言printf函数
#include<stdio.h> //int float double short char long int main() { //int printf(const char *for ...
- 【C语言】printf函数详解
C语言printf函数详解 一.相关基础知识 请求printf()打印变量的指令取决于变量的类型,例如打印整数用%d符号,打印字符用%c符号,这些符号称为转换说明(conversion specifi ...
- MFC 中的 “printf” 函数
怀念C语言的我,MFC没法使用的C语言printf函数,于是: int MFCprintf(const char* m_data, ...){ CString str; char printf_buf ...
- C语言中可变参数的原理——printf()函数
函数原型: int printf(const char *format[,argument]...) 返 回 值: 成功则返回实际输出的字符数,失败返回-1. 函数说明: 使用过C语言的人所再熟悉不过 ...
随机推荐
- HDU 3790 (最短路 + 花费)
题意: 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. #include<bits/stdc ...
- C++ 实验六
Part.2 // 合并两个文件内容到一个新文件中. // 文件名均从键盘输入 #include <iostream> #include <fstream> #include ...
- python数据类型小结
变量 变量是 为了存储程序 运算过程中的一些中间结果,为了方便日后调用. 变量的命名规则1.要有描述性2.变量名只能_,数字,字母组成,不可以是特殊字符(#)3.不能以中文为变量名4.不能以数字开头5 ...
- 7,数据类型转换,set 集合,和深浅copy
str转换成list 用split list转换成str 用join tuple转换成list tu1 = (1,2,3) li = list(tu1)(强转) tu2 = tuple(li)(强 ...
- Java-替换字符串中的字符
package com.tj; public class MyClass implements Cloneable { public static void main(String[] args) { ...
- jsonp实现跨域访问json数据
前台js function init() { $.ajax({ url: 'http://localhost:8012/index.json', dataType: "jsonp" ...
- 从士兵到程序员再到 SOHO 程序员 (三) - 游击战与阻力
从士兵到程序员再到 SOHO 程序员 (三) - 游击战与阻力 原文地址:http://blog.huhao.name/blog/2014/03/01/become-a-freelancer-3/ 作 ...
- Masonry练习
tableView的cell自动适应,scrollview自动适应,自定义自动布局控件 demo链接:http://pan.baidu.com/s/1jHsrGwQ
- 算法复习——有源汇上下界可行流(bzoj2396)
题目: Description We are supposed to make a budget proposal for this multi-site competition. The budge ...
- spring之Autowire
当使用spring为一个对象的属性注入时,通常使用xml文件的property元素和ref属性,但是我们也可以使用spring中的autowire进行注入 使用方法如下 <bean id=&qu ...