将空指针传递给 printf 转换

printf%s 转换表明相应的参数是指向字符类型数组的初始元素的指针。空指针不指向任何字符类型数组的初始元素,因此未定义以下行为:

char *foo = NULL;
printf("%s", foo); /* undefined behavior */

但是,未定义的行为并不总是意味着程序崩溃 - 某些系统采取措施来避免在取消引用空指针时通常发生的崩溃。例如,已知 Glibc 可以打印

(null)

对于上面的代码。但是,在格式字符串中添加(仅)换行符会导致崩溃:

char *foo = 0;
printf("%s\n", foo); /* undefined behavior */

在这种情况下,它发生是因为 GCC 有一个优化,将 printf("%s\n", argument); 转换为使用 puts(argument) 调用 puts,而 Glibc 中的 puts 不处理空指针。所有这些行为都符合标准。

请注意,空指针空字符串不同。因此,以下内容有效且没有未定义的行为。它只会打印一个换行符

char *foo = "";
printf("%s\n", foo);