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

调用fscanf传入malloc(0)分配指针未触发SIGSEGV的原因问询

现象原因解释
  • C语言本身无内置边界检查机制
    C语言标准没有要求对动态内存、数组做访问边界校验,写入超出分配范围的内存属于未定义行为。未定义行为没有任何强制约束,程序可能直接崩溃、输出异常结果,也可能看起来完全正常运行,不报错不代表代码逻辑合法,只是当前运行环境下暂时没有触发异常而已。
  • malloc(0)的实现特性
    C标准中malloc(0)的行为是实现定义的:要么返回空指针,要么返回一个合法但不允许解引用的非空指针。主流C标准库(如glibc、MSVC CRT)都会返回一个满足最小内存对齐要求的非空地址,但该地址指向的空间并不属于当前程序的合法可写范围,后续写入内容本质都是越界访问。
  • fscanf无缓冲区校验逻辑
    你使用的%[^\n]格式符本身没有任何长度校验能力,只要传入一个指针,fscanf就会不断把读取到的内容写入该指针指向的后续地址,完全不会判断你为这个指针分配了多大的内存空间,其他没有明确指定长度限制的stdio输入函数都存在同样的问题。
  • 未触发报错是偶然现象
    当前测试环境下没有触发崩溃,只是因为你越界写入的内存暂时没有被其他程序逻辑占用、也没有触发操作系统的页访问保护(比如没有写到堆的保护页、没有覆盖其他正在使用的内存数据),一旦运行环境变化、输入内容变长,大概率会触发段错误、数据污染等异常,这类越界写入也是典型的缓冲区溢出漏洞来源。
修复建议
  • 分配内存时明确申请足够容纳目标内容的空间,比如要存最长1023字节的字符串,就申请1024字节的空间(预留字符串结束符\0的位置)
  • 使用fscanf时给格式符加长度限制,比如%1023[^\n],限制最多读取1023个字符,避免溢出
  • 更安全的做法是先用fgets读取整行内容到固定长度缓冲区,再用sscanf解析内容,降低溢出风险
  • 增加malloc返回值的判空逻辑,避免空指针解引用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:01