C代码如下。我知道代码会导致核心转储。我们可以看到什么输出?不同的平台有什么不同吗?
#include <stdio.h>
int main(){
printf("abc\n123");
printf("IHJ");
printf("%d", int* 0);
return 0;
}
答案 0 :(得分:1)
我知道代码会导致核心转储
嗯,遗憾的是,您的信息错误。 以上代码无法编译。请继续阅读。
您的代码中存在第三个printf()
的问题。
printf("%d", int* 0);
无效且无法编译。 %d
需要int
变量,而不是int
keyoword本身。
即使int*
意味着是cast
,例如
printf("%d", (int*)0);
也是错的。您需要%p
来打印指针(地址)。为特定格式说明符提供无效类型的参数会调用undefined behaviour。
FWIW,当你面对UB时, 可能 会出现分段错误和核心转储。
否则,只要您为printf()
提供的格式说明符提供所需的参数类型和数量,就会有明确定义的行为。
要迂腐,int main()
应为int main(void)
答案 1 :(得分:1)
printf("%d", int* 0);
这不会编译。如果你的意思是
printf("%d", (int*)0);
然后它也是错误的(使用错误的格式说明符是未定义的行为),因为打印指针的格式说明符是%p
。所以你的意思是
printf("%p", (void*) (int*)0);
然后由%p
打印的结果表示是实现定义的。
C标准状态
C11,7.21.6格式化输入/输出功能
参数应该是指向void的指针。指针的值是 转换为一系列打印字符,在 实现定义的方式。
答案 2 :(得分:0)
如果第三个printf()
具有如下所示的确切位置:
printf("%d", int* 0);
这将导致编译器错误。但是,如果你的意思是
printf("%d", (int *)0);
有两个问题:
"%p"
作为指针。printf()
可能会处理它与有效指针值的不同。无论哪种方式,都不能保证核心转储或显示任何特定行为。它甚至可能显示没有错误的行为(最坏的情况 - 你没有注意到出错的地方)。 “未定义行为”的本质是任何事情都可能发生。你的电脑可能会飞走。
答案 3 :(得分:0)
如前所述,
printf( "%d", int* 0 );
不会编译,因为int* 0
不是合法表达。
如果写成
printf ( "%d", (int *) 0 );
然后行为 undefined ,因为%d
期望其对应的参数具有类型int
,而不是int *
。这很可能不导致核心转储,但任何输出都不应该被信任。
如果写成
printf( "%p", (int *) 0 );
行为仍未未定义,因为%p
需要void *
(这是您需要将指针值显式转换为{{}的少数几个地方之一C)中的1}}。同样,这很可能不导致核心转储,但任何输出都不应该被信任。
如果写成
void *
然后它应该打印出一个NULL指针的实现定义值,该指针可能不是或不是0(假设你使用换行符或调用printf( "%p", (void *) 0 );
,无论如何)。
如果写成
fflush( stdout )
然后这个很可能导致核心转储。严格来说,由于您要取消引用无效指针,行为仍未定义,并且可能存在这样做的系统不会导致立即崩溃。