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语言的人所再熟悉不过 ...
随机推荐
- 使用VMware克隆出来的新虚拟机无法联网-问题解决记录
背景: 使用VMware克隆出来的新虚拟机无法联网,重启网卡出现如下图提示: 继续输入#ifup ens33 提示: ens33: unknown interface: No such device ...
- (原)剑指offer跳台阶和矩形覆盖
跳台阶 时间限制:1秒空间限制:32768K 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 分析同样为斐波那契数列边形这样的题肯定有公式 设 ...
- Solr通过配DIH对数据库数据做索引
1 加入相关jar包 将2个相关jar包复制到/opt/solr-7.7.1/server/solr-webapp/webapp/WEB-INF/lib文件夹下 jar包名称 solr-dataimp ...
- ctci(1)
// // main.cpp // proj1 // // Created by Yuxin Kang on 8/24/14. // Copyright (c) 2014 Yuxin Kang. Al ...
- linux 环境下bash脚本中找不到命令
mr.sh: line 1: HADOOP_CMD: command not found mr.sh: line 4: INPUT_FILE_PATH: command not found mr.sh ...
- luogu2634 聪聪可可
点分治裸题 #include <iostream> #include <cstdio> using namespace std; int n, uu, vv, ww, ans, ...
- BZOJ 3143 [Hnoi2013]游走 ——概率DP
概率DP+高斯消元 与博物馆一题不同的是,最终的状态是有一定的概率到达的,但是由于不能从最终状态中出来,所以最后要把最终状态的概率置为0. 一条边$(x,y)$经过的概率是x点的概率$*x$到$y$的 ...
- java面试题之什么是ThreadLocal?底层如何实现的?
ThreadLocal是一个解决线程并发问题的一个类,用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术.但是当我们不想使用同步的时 ...
- C++ string 类中的 assign()函数
C++ string 类的成员函数,用于拷贝.赋值操作,它们允许我们顺次地把一个 string 对象的部分内容拷贝到另一个 string 对象上. 函数原型 string &operator= ...
- MVC 上传文件的方法
这两天又开始研究MVC了,期间断断续续已经搞了好久了,可是都没坚持下来.囧!这次一定坚持搞出来一个名堂. 废话少说,直接上代码. 前台引擎采用Razor @model System.Web.HttpP ...