C语言四维数组代码报Segmentation fault段错误问题咨询
问题描述
运行如下C语言代码时触发Segmentation fault(段错误):
#include <stdio.h> #include <math.h> int main() { int n = 4; float A[n][n][n][n]; A[n][n][1][1] = 1; A[n][n][1][2] = 0; A[n][n][1][3] = -3; A[n][n][1][4] = 0; A[n][n][2][1] = 1; A[n][n][2][2] = 0; A[n][n][2][3] = -3; A[n][n][2][4] = 0; return 0; }
错误分析
段错误的核心诱因是数组下标越界写入:
- C语言数组默认采用0基下标,即长度为N的数组,合法下标范围是0~N-1。代码中定义的四维数组每一维长度为n=4,因此每一维允许访问的下标最大值为3。
- 所有赋值语句的前两维都传入了下标值
n(即4),已经完全超出数组的内存边界,访问位置落在了数组所属内存块之外;另外部分语句最后一维使用下标4,同样属于越界访问。 - 向未被程序申请的内存地址写入数据,会触发操作系统的内存保护机制,直接终止进程抛出段错误。
额外注意:代码中声明的是C99标准支持的变长数组(VLA),内存分配在进程栈空间上,栈空间默认大小通常只有几MB,如果后续将n设置为较大值,即使下标合法也可能因为栈空间不足触发溢出错误,大尺寸数组建议使用malloc在堆空间分配。
修正方案
如果需要沿用1~n的下标使用习惯,可以在定义数组时将每一维长度设为n+1,预留出下标0的位置即可,修正后代码如下:
#include <stdio.h> #include <math.h> int main() { int n = 4; float A[n+1][n+1][n+1][n+1]; A[n][n][1][1] = 1; A[n][n][1][2] = 0; A[n][n][1][3] = -3; A[n][n][1][4] = 0; A[n][n][2][1] = 1; A[n][n][2][2] = 0; A[n][n][2][3] = -3; A[n][n][2][4] = 0; return 0; }
如果不需要用1基下标,把所有访问的下标统一减1适配0基规则也可以。
内容的提问来源于stack exchange,提问作者Luka Kaličanin
相关产品推荐
相关产品推荐

