如何理解snprintf的处理NULL参数?

Nan*_*iao 2 c

检查以下简单C程序:

#include <stdio.h>

int main(void)
{
    char str[4] = {1, 1, 1, 1};
    snprintf(str, sizeof(str), "%s%s", "a", NULL);

    printf("%s\n", str);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

构建并运行它Linux:

$ gcc test.c
$ ./a.out
a(n
Run Code Online (Sandbox Code Playgroud)

如何理解输出中(n出现的" "字符a?我希望当snprintf遇到NULL争论时,它会停止处理.顺便说一下,我无法从snprintf 手册中找到相关信息.

AnT*_*AnT 10

如果snprintf(fprintf,printf或从该系列中的任何功能)遇到一个空指针参数的%s格式说明,该行为是不确定的.在现实生活中,不是崩溃或行为不可预测,许多标准库实现更喜欢将(null)序列插入到收件人缓冲区中.这是你在实验中观察到的东西-那开始(null)snprintf成功地适应这个的剩余空间str受主阵列.


很久以前有一个故事(即使互联网,它永远不会忘记,似乎已经忘记了它),关于一家大型美国电信公司的普通客户,他将"null"注册为他的电子邮件ID,因此获得"null @" company.com"作为他的电子邮件地址.突然,他开始收到大量内部公司的电子邮件,其中包含其他客户的个人数据.如果我没记错的话,它是由内部公司软件中的一个错误引起的,其中一个空指针被传递给负责形成目标电子邮件地址的函数.而且该函数不是崩溃,而是采用类似的故障安全行为来响应空指针参数.在有人将"null@company.com"注册为有效的电子邮件地址之前,该错误一直未被发现.

  • @Yunnosch:7.21.6.1/8"参数应该是指向字符类型数组的初始元素的指针." 空指针不符合该要求. (2认同)

Som*_*ude 7

snprintf函数尝试写入"(null)"您的字符串,但由于目标只有四个字符,因此您永远不会获得超过三个字符的字符串(加上终结符).

请注意,插入"(null)"不是由标准指定的,为"%s"格式说明符传递NULL参数实际上是未定义的行为.

  • @Yunnosch:[C11§7.1.4库函数的使用1](https://port70.net/~nsz/c/c11/n1570.html#7.1.4p1) - 除非明确说明,否则以下各项陈述均适用否则在下面的详细描述中:如果函数的参数具有无效值(例如函数域外的值,或者程序地址空间外的指针,或空指针,[...]行为未定义._ (4认同)