C++ 为什么';这不是你的错吗

C++ 为什么';这不是你的错吗,c++,c,segmentation-fault,printf,C++,C,Segmentation Fault,Printf,我偶然发现了一些“有趣的”东西,我无法解释为什么这种行为不连贯 检查此代码 char buf[100]; sprint(buf,"%s",bla); 简单,对。当bla是NULL指针时,很容易理解发生了什么 这应该总是正确的 在一台机器上,可执行文件发生故障,在另一台机器上(我的开发机器),一切照旧 我的devel电脑正在运行Windows7,我正在使用gcc/MingW进行编译。发生此崩溃的计算机是XP,它确实安装了visualstudio 6 为什么我的电脑不会崩溃?因为将空引用打印为字符

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

检查此代码

char buf[100];
sprint(buf,"%s",bla);
简单,对。当
bla
NULL
指针时,很容易理解发生了什么

这应该总是正确的

在一台机器上,可执行文件发生故障,在另一台机器上(我的开发机器),一切照旧

我的devel电脑正在运行
Windows7
,我正在使用
gcc/MingW
进行编译。发生此崩溃的计算机是
XP
,它确实安装了
visualstudio 6


为什么我的电脑不会崩溃?

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

与其他printf函数相同:

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

除此之外,segfault永远无法保证。如果它发生了,在某个地方有一个错误;但在某个地方出错并不意味着错误

这应该总是正确的

否。这取决于编译器标准库附带的
sprintf
函数的实现

据我所知,
sprintf
规范并没有说应该提供非空地址

这应该总是正确的


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

ISO C99:7.19.6.3 printf函数

概要

#包括
int printf(常量字符*限制格式,…);
printf函数相当于fprintf,在printf的参数之前插入参数stdout。

7.19.6.1 fprintf功能

7.19.6.1.9

如果转换规范无效,则行为**未定义**。如果有任何论点是正确的
对应转换规范的类型不正确,行为**未定义**。

因此,您的代码调用未定义的行为(ISO C99 3.4.3) 使用不可移植或错误的程序结构或错误的数据时的行为, 本国际标准对其**无要求**]

这应该总是正确的


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

这完全取决于bla当时指向的是什么。 sprintf()将复制bla指向的所有字符,直到遇到零(0x00)字符

如果它在达到buf[100]的限制之前遇到一个零字符,那么就不存在SEGFULT,因为我们没有写入超过buf限制的内容


此外,在某些系统中,如果bla指向受读访问保护的内存区域,则在读取数据时也可能会导致SEGFULT。

仅提一下:我知道这是测试代码,但在大多数情况下,您可能应该使用
snprintf()
而不是
sprintf()
。除非您需要测试您的代码是否与严重不稳定的编译器兼容,否则我会考虑用本世纪的东西取代Visual Studio 6。正如所有答案所说,这确实是一种未定义的行为——但是,只是想一想:您确定bla为空吗?是否可能未初始化?这是系统之间存在差异的一个更常见的原因。+1:但这引发了以下问题:是否有办法确保某些东西会导致
SEGFAULT
?(
kill my_program SEGFAULT
不是答案)
raise(SIGSEGV)或者,虽然没有标准说这必须起作用,*(char*)0=0;也很可靠。很好的研究,Prasoon,
+1
来自我!有一天,我将制作一个编译器,每次调用未定义的行为时都开始播放Valkyrie的飞行。
 #include <stdio.h>
 int printf(const char * restrict format, ...);