Grace's Dev Site
write关于我
闭坑指南 · C#经典错误

未定义行为 UB

C 里标准未规定的操作:越界、有符号溢出、use-after-free 等,编译器可任意假设。

未定义行为(Undefined Behavior)

未定义行为指 C 标准没有规定结果的操作。编译器可以:

  • 优化掉「永远走不到」的分支
  • 假设指针不会越界,从而重排指令
  • -O2 下让原本「好像能跑」的代码彻底崩掉

常见 UB 来源

| 类型 | 例子 | |------|------| | 越界访问 | arr[10]arr 长度只有 3 | | 有符号溢出 | INT_MAX + 1 | | 悬空指针 | free 后继续读写 | | 未初始化读取 | 局部变量未赋值就用 | | 违反有效指针规则 | 错误类型的指针转换 |

与「实现定义」「未指定」的区别

  • 实现定义:编译器必须选一种行为并写进文档(如 char 有符号与否)
  • 未指定:标准允许多种结果,但程序仍合法
  • 未定义:什么都可能发生,包括看起来正常、崩溃、或删掉你的代码

工程建议

  1. 开启警告:-Wall -Wextra -Werror(逐步收紧)
  2. 用 Valgrind / ASan 查内存问题
  3. 不要写「我知道编译器会怎么优化」的代码——换版本就可能炸

下面示例只做合法访问。想感受 UB 可在本地实验越界(勿在生产代码里依赖结果)。

在线运行 C

GCC (Piston)