为了账号安全,请及时绑定邮箱和手机立即绑定

如果用错误的格式字符串调用printf会发生什么?

如果用错误的格式字符串调用printf会发生什么?

C++
喵喵时光机 2019-10-22 22:06:30
或者换句话说:可能错误printf/ fprintf十进制整数(%d,%u,%ld,%lld)格式化字符串导致程序崩溃或导致未定义的行为?Cosinder的以下代码行:#include <iostream>#include <cstdio>int main() {    std::cout << sizeof(int) << std::endl              << sizeof(long) << std::endl;    long a = 10;    long b = 20;    std::printf("%d, %d\n", a, b);    return 0;}在32位架构上的结果:4410, 2064位体系结构的结果:4810, 20无论如何,程序都会打印出预期的结果。我知道,如果该long值超出int范围,程序将打印错误的数字-这很丑陋,但不会影响程序的主要目的-但是除此之外,还会发生意外情况吗?
查看完整描述

3 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

如果用错误的格式字符串调用printf会发生什么?


什么都可能发生。这是未定义的行为!

未定义的行为意味着任何事情都可能发生。它可能会向您显示预期的结果,也可能不会,或者可能导致崩溃。任何事情都有可能发生,您只能怪自己,不要怪自己。


参考:


c99标准:7.19.6.1:

第9段:


如果转换规范无效,则行为未定义。225)如果任何参数都不是对应coverage规范的正确类型,则行为未定义。


查看完整回答
反对 回复 2019-10-22
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

哦,是的-printf取决于格式字符串,以确定接下来要获取的变量的大小和类型。当格式字符串错误时,它可能会尝试获取一个甚至不存在的变量,从而可能产生所有后果。


查看完整回答
反对 回复 2019-10-22
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

这是未定义的行为-规范中没有任何内容告诉编译器设计器(或C库设计器)应如何处理,因此允许他们执行任何操作。

在实践中,完全取决于数字的解释是其中之一,最有可能的是,这样做绝对不会给您带来任何好处。真正糟糕的是,当您将字符串与整数格式混合时-字符串会很好地打印为(奇怪的,也许是)数字,但是当数字作为字符串传递时,数字不太可能“起作用”-因为字符串是指向第一个地址的指针字符-大多数数字在典型系统中不是有效的指针,因此会崩溃。

但是,没有任何保证。在您的64位示例中,很明显该数字是“ little endian”。尝试使用0x100000000进行同样的操作,它会显示0-因为其余的数字都会丢失。


查看完整回答
反对 回复 2019-10-22
  • 3 回答
  • 0 关注
  • 514 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信