为什么不这个段落错误

时间:2010-07-13 09:15:21

标签: c++ c segmentation-fault printf

我偶然发现了一些“有趣”的东西,我无法理解为什么行为不连贯。

检查此代码。

char buf[100];
sprint(buf,"%s",bla);

简单,对。当blaNULL指针时,很容易理解发生了什么。

这应该始终是段错误的??

在一台机器中,可执行文件段错误,在另一台机器上(我的开发机器),它就像往常一样。

我的devel PC正在运行Windows7,我正在使用gcc/MingW进行编译。崩溃的计算机是XP,并且安装了Visual studio 6

为什么我的电脑没有崩溃?

6 个答案:

答案 0 :(得分:24)

ISO C99: 7.19.6.3 The printf function

概要

 #include <stdio.h>
 int printf(const char * restrict format, ...);

The printf function is equivalent to fprintf with the argument stdout interposed before the arguments to printf.

7.19.6.1 The fprintf function

7.19.6.1.9

If a conversion specification is invalid, the behavior is **undefined**. If any argument is not the correct type for the corresponding conversion specification, the behavior is **undefined**.

因此,您的代码会调用未定义的行为 [(ISO C99 3.4.3) behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes **no requirements**]

  

这应该始终是段错误的??

不一定,未定义的行为意味着任何都可能发生。

答案 1 :(得分:11)

  

这应该始终是段错误的??

没有。这会调用未定义的行为。分段错误只是调用UB的许多可能结果之一。

答案 2 :(得分:3)

因为打印空引用作为字符串是(据我所知,未经标准验证)未定义。许多系统只会在结果中输出(null)

与其他printf函数相同:

printf ("%s", NULL); // Outputs (null) to the console on some systems but can crash others

答案 3 :(得分:1)

除此之外,从不保证段错误。如果发生,某处出现错误;但在某处出现错误并不意味着会出现段错误。

答案 4 :(得分:1)

  

这应该始终是段错误的??

没有。它取决于编译器标准库附带的sprintf函数的实现。

据我所知sprintf规范并未说明您应提供非空地址。

答案 5 :(得分:0)

这完全取决于当时bla指向的内容。 sprintf()将执行的操作是复制bla指向的所有字符,直到遇到零(0x00)字符。

如果在达到buf [100]的限制之前遇到零字符,那么就没有段错误,因为我们没有超出buf限制。

此外,在某些系统中,如果bla指向读取访问受保护的内存区域,则一旦读取数据,它也可能导致段错误。