当将空指针传递给snprintf函数时的预期行为

4
这段代码的预期行为是什么?
char * aNullPointer = 0;
snprintf (res, 128, "Testing %s null pointer",aNullPointer);

请注意,我故意试图取消引用我的空指针aNullPointer

行为1)res指向字符串“Testing(null)null pointer”

行为2)段错误

似乎我的平台会出现不同的行为。一些snprintf实现执行健全性检查,而其他实现则不执行。

最常见的行为是什么?


2
没有预期的行为。行为是未定义的。 - R. Martinho Fernandes
2
我曾经尝试过这个,结果煎饼出现在了CD插槽里。 - Luchian Grigore
1
@LuchianGrigore 比鼻妖好一些吧 - cnicutar
3
@LuchianGrigore,编译器和平台!我要它! - unkulunkulu
1
预期的行为是太阳变成绿色,地球停止旋转。也就是说,这是未定义的。 - Ed Heal
5个回答

9

这是一种未定义行为 - 没有什么可以期望的结果。一些实现检查NULL并将其替换为"nil"或"null"只是一种礼貌,您不能完全依赖它。


我想,snprintf 应该是一个“更安全”的版本,因此它可能会对空值进行检查。但当然,你是正确的! - willcode.co

4
这里的其他答案有一个需要注意的地方:如果第二个参数(指定要写入的字节数)为零,则可以将空指针作为第一个参数传递给 snprintf

来自 C11 标准(我强调的):

snprintf 函数等同于 fprintf,不同之处在于输出被写入到一个数组中(由参数 s 指定),而不是写入到流中。 如果 n 为零,则不会写入任何内容,s 可以是空指针。

这可以用于首先找出 snprintf 要写入多少字节,以便在第二次调用 snprintf 时分配一个相应大小的缓冲区进行写入,如 https://dev59.com/_W865IYBdhLWcg3whe5f#10388547 所示。
但是,如果 n 不为零,则行为未定义。

2

未定义行为。不要这样做。

当将空指针传递给%s时,glibc将使用(null),但不要依赖此功能!


1

从某种意义上说,没有预期的行为。实际上,在标准中明确指出,行为在相当广泛的意义上是未定义的:它可以工作,也可以导致段错误,还可以格式化您的硬盘等等。您应该自己检查NULL指针。


0

如果我们参考Opengroup规范,似乎对于这种情况没有定义的行为:

参数应该是指向字符数组的指针。从数组中写入字节直到(但不包括)任何终止空字节。如果指定了精度,则最多只能写入那么多字节。如果未指定精度或精度大于数组的大小,则应用程序应确保数组包含空字节。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接