gpt4 book ai didi

c++ - 为什么 fprintf 在缺少 width 参数时导致内存泄漏和行为不可预测

转载 作者:太空狗 更新时间:2023-10-29 19:47:33 25 4
gpt4 key购买 nike

以下简单程序的行为异常。有时它打印“0.00000”,有时它打印的“0”多于我数不过来。有时它会用完系统上的所有内存,然后系统要么终止某些进程,要么因 bad_alloc 而失败。

#include "stdio.h"

int main() {
fprintf(stdout, "%.*f", 0.0);
}

我知道这是对 fprintf 的错误使用。应该有另一个参数指定格式的宽度。令人惊讶的是,这种行为是如此不可预测。有时它似乎使用默认宽度,而有时它会非常严重地失败。难道不能让它总是失败或总是使用一些默认行为吗?

我在工作的一些代码中发现了类似的用法,并花了很多时间弄清楚发生了什么。它似乎只发生在调试版本中,但在使用 gdb 调试时不会发生。另一个奇怪的是,通过 valgrind 运行它会始终打印许多“0”的情况,否则这种情况很少发生,但内存使用问题也永远不会发生。

我正在运行 Red Hat Enterprise Linux 7,并使用 gcc 4.8.5 进行编译。

最佳答案

正式来说,这是未定义的行为。

至于你在实践中观察到的:
我的猜测是 fprintf 最终使用未初始化的整数作为要输出的小数位数。那是因为它会尝试从调用者未写入任何特定值的位置读取一个数字,因此您将只获取恰好存储在那里的任何位。如果这恰好是一个巨大的数字,fprintf 将尝试分配大量内存来在内部存储结果字符串。这将解释“内存不足”部分。

如果未初始化的值不是那么大,分配就会成功,最终会得到很多零。

最后,如果随机整数值恰好是 5,您将得到 0.00000

Valgrind 可能会始终如一地初始化您的程序看到的内存,因此行为变得确定。

Could this not be made to always fail

我敢肯定,如果您使用 gcc -pedantic -Wall -Wextra -Werror,它甚至无法编译。

关于c++ - 为什么 fprintf 在缺少 width 参数时导致内存泄漏和行为不可预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56356453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com