C语言为什么可以访问数组未声明位置的元素且不报错?
C语言数组越界访问无报错的原因
你这段代码属于典型的数组越界访问,之所以没有报错还能正常输出23,核心原因如下:
- C语言设计偏向底层性能优化,C标准本身没有强制要求编译器或运行时环境做数组下标越界检查,越界访问属于「未定义行为」范畴,没有规范要求必须触发报错,运行结果完全不可预期:可能直接崩溃、可能输出乱码,也可能像你这个案例一样碰巧正常运行。
- C语言的数组下标只是语法糖,
data[n]等价于*(data + n),编译器只负责计算「数组首地址 + n * 元素类型长度」的内存地址,不会校验n是否在数组声明的长度范围内。只要计算出来的这个内存地址属于当前进程有权限读写的区域(比如刚好落在当前栈帧的可写范围内,没有触发操作系统的页保护中断),写入和读取操作就不会触发段错误。 - 你能正常输出23的逻辑非常简单:你刚刚往这个可访问的非法地址里写入了23,紧接着读取自然能读到刚写入的值,这不代表程序逻辑正确,这类代码在不同编译环境、不同操作系统下运行,随时可能出现崩溃、其他变量被意外篡改等异常问题。
如果想要提前发现这类问题,可以在编译时开启警告选项,比如GCC/Clang编译器添加
-Wall -Wextra -O2参数,大部分静态可识别的越界场景会触发编译警告;也可以添加-fsanitize=address编译参数,运行时会精准定位越界访问的位置。
内容的提问来源于stack exchange,提问作者Tenko
相关产品推荐
相关产品推荐

