正在将NULL传递给printf%s #包括 #包括 int main(){ char*ptr=NULL; printf(“%s”,ptr);//输出为空 //printf(“%s\n”,ptr);//添加**\n**给出分段错误 返回0; }

正在将NULL传递给printf%s #包括 #包括 int main(){ char*ptr=NULL; printf(“%s”,ptr);//输出为空 //printf(“%s\n”,ptr);//添加**\n**给出分段错误 返回0; },c,C,第一个printf输出:(null)。但是为什么第二个printf的输出是:分段错误(堆芯转储)只需添加:\n printf(“%s”,ptr) 这里printf需要一个有效指针,指向以null结尾的字符串,您不能将null传递给它。如果这样做,您将触发未定义的行为,并且无法解释程序的输出 另外,我已经找到了一个答案,其中可能有一些关于你可能感兴趣的事情的细节。看见事实上,你的问题似乎是那个问题的重复 printf(“%s”,ptr) 这里printf需要一个有效指针,指向以null结尾的字符串

第一个
printf
输出:
(null)
。但是为什么第二个
printf
的输出是:
分段错误(堆芯转储)
只需添加:
\n

printf(“%s”,ptr)

这里
printf
需要一个有效指针,指向以null结尾的字符串,您不能将null传递给它。如果这样做,您将触发未定义的行为,并且无法解释程序的输出

另外,我已经找到了一个答案,其中可能有一些关于你可能感兴趣的事情的细节。看见事实上,你的问题似乎是那个问题的重复

printf(“%s”,ptr)

这里
printf
需要一个有效指针,指向以null结尾的字符串,您不能将null传递给它。若这样做,将触发未定义的行为,并且无法对程序的输出进行推理

另外,我已经找到了一个答案,其中可能有一些关于你可能感兴趣的事情的细节。看见事实上,你的问题似乎是那个问题的重复

如我所知 printf实际上使用了一个名为write()的系统调用,内核将使用该调用来写入stdout文件描述符。在这种情况下,\n会导致指针移动到未标记的区域,并尝试从那里将数据写入标准输出文件描述符会导致此行为

从SO本身找到了一个很好的参考

我能看出来 printf实际上使用了一个名为write()的系统调用,内核将使用该调用来写入stdout文件描述符。在这种情况下,\n会导致指针移动到未标记的区域,并尝试从那里将数据写入标准输出文件描述符会导致此行为

从SO本身找到了一个很好的参考


一些
printf
实现会考虑
NULL
字符串参数,但其中一些实现有“bug”,请参阅

不管怎样,C标准说:

参数应该是指向数组初始元素的指针 字符类型


如果不是,那么这是一个未定义的行为。您所面临的行为就是其中之一。

一些
printf
实现会考虑
NULL
字符串参数,但其中一些实现有“bug”,请参阅

不管怎样,C标准说:

参数应该是指向数组初始元素的指针 字符类型


如果不是,那么这是一个未定义的行为。您所面临的行为就是其中之一。

背后的技术原因是:

如果你写了这样的陈述

#include<stdio.h>
#include<string.h>

int main() {
    char *ptr = NULL;

    printf("%s", ptr);//The output is null
    //  printf("%s\n", ptr); //addition of **\n** give segmentation fault 

    return 0;
}
一些编译器(即带有优化的gcc)将“优化”它,以:

put()
的glibc实现不会在空指针上打印
(null)
(与printf一样),但会显示错误


在未激活优化的情况下调用gcc时,不会进行此替换,并且
printf(“%s\n”,NULL)将不会分离故障


此行为符合标准,因为将空指针传递到
printf()
会调用“未定义的行为”。

背后的技术原因是:

如果你写了这样的陈述

#include<stdio.h>
#include<string.h>

int main() {
    char *ptr = NULL;

    printf("%s", ptr);//The output is null
    //  printf("%s\n", ptr); //addition of **\n** give segmentation fault 

    return 0;
}
一些编译器(即带有优化的gcc)将“优化”它,以:

put()
的glibc实现不会在空指针上打印
(null)
(与printf一样),但会显示错误


在未激活优化的情况下调用gcc时,不会进行此替换,并且
printf(“%s\n”,NULL)将不会分离故障


此行为符合标准,因为将空指针传递到
printf()
会调用“未定义的行为”。

在法律术语中:这是未定义的行为,所以任何东西,特别是任何输出,都是可以接受的。日常用语:垃圾输入,垃圾输出。@haccks你有没有删除第二次printf的注释?@Rishi你用过哪个编译器?@AnilKumar 3.4版。2@Rishi我在法律上使用了gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2。它是未定义的行为,所以任何东西,特别是任何输出,都是可以接受的。日常用语:垃圾输入,垃圾输出。@haccks你有没有删除第二次printf的注释?@Rishi你用过哪个编译器?@AnilKumar 3.4版。2@Rishi我使用过gcc(Ubuntu 4.8.2-19ubuntu1)4.8.2.
write()
在处理管道的末尾被调用,处理管道从用户程序调用
printf()
开始
write()
很可能不会从原始字符串(此处不存在)读取传输到设备的数据,而是从C标准库的缓冲I/O使用的缓冲区读取数据。(可能情况与无缓冲I/O不同。不确定。)现在还不清楚换行符(毕竟只是复制到输出中的字符)应该如何更改任何内容。换行缓冲会在缓冲区中出现新行时引发write()调用。这里的缓冲区为空(NULL)。write的语法{man write(3)}类似于ssize_t write(int fildes,const void*buf,size_t nbyte);因此,如果buf在尝试从那里获取某些东西时为NULL,则可能会导致segfault。如果思考过程错误,我希望得到纠正。
printf
“原因”(这是正确的——在您的帖子中,您写的是“a”,这是错误的)a
write
,true。但是
printf
首先将其生成的格式化字符复制到一个单独的缓冲区(您可以使用该缓冲区进行设置)。
write
使用该缓冲区调用(不使用原始数据)。该缓冲区总是正常的。这里出现问题的原因是printf函数在试图将数据复制到C标准库具有的内部缓冲区时取消了对空指针的引用
puts(ptr);