You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何sscanf(3)允许将NULL指针作为%s转换的指针参数?

为什么sscanf接受NULL作为%s参数时不触发段错误?

这本质是未定义行为的具体表现,结合常见C标准库(比如glibc)的实现逻辑,可拆解为两个核心原因:

1. sscanf对NULL参数的处理逻辑

C标准明确要求,使用%s格式符调用sscanf时,必须传入指向有效字符数组的指针。传入NULL属于违反函数前置条件的未定义行为——理论上程序可以出现任何结果,但glibc等主流标准库实现会对sscanf的可变参数做额外检查:当检测到%s对应的参数是NULL时,会直接跳过该转换操作,不会尝试写入内存,因此不会触发段错误(SIGSEGV)。

你的gdb会话片段也验证了这一点:

Breakpoint 1, main () at SRP-32744.c:10
10        strcpy(name, "Mack, Anna");
(gdb) n
12        pHelp=(char *) NULL;
(gdb) n
13        sscanf(name, "%s", pHelp);
(gdb) p pHelp
$1 = 0x0
(gdb) n
15        printf("after sscanf()\n");

执行sscanf后程序正常走到了printf语句,没有崩溃。

2. strcpy触发崩溃的原因

strcpy的设计逻辑和sscanf完全不同:它会直接访问源指针指向的内存进行读取操作,不会做NULL指针检查。当你把NULL作为strcpy的源指针传入时,程序会尝试读取地址0处的内存,这属于非法内存访问,操作系统会立刻发送SIGSEGV信号终止程序,也就是你看到的延迟崩溃。

总结

这种延迟崩溃的问题非常隐蔽,根源在于未定义行为的不确定性——不同的标准库实现可能对sscanf的NULL参数有不同处理(比如某些小众实现可能直接崩溃)。编写C代码时,必须确保传给sscanf的%s参数是有效的非NULL指针,绝对不能依赖这种未定义行为。

内容的提问来源于stack exchange,提问作者guru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:33:29