下面的代码有什么问题?C编译器显示error: 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;
}
所有这些赋值都访问了定义的可变长度数组之外的内存。
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;
表示数组的每个维度的有效索引范围为[0, n )
。因此表达式A[n]
无效。
你的意思似乎是以下任务
A[0][0][0][0]=1;
A[0][0][0][1]=0;
A[0][0][0][2]=-3;
A[0][0][0][3]=0;
A[0][0][1][0]=1;
A[0][0][1][1]=0;
A[0][0][1][2]=-3;
A[0][0][1][3]=0;
如果你定义了一个长度为N的数组,那么对最后一个元素的访问是在第N-1索引处,对第一个元素的访问是在索引0处,因为索引从0开始到N-1结束。
所以你的代码应该是这样的:#include<stdio.h>
#include<math.h>
#define N 4
int main() {
float A[N][N][N][N];
A[N-1][N-1][0][0]=1;
A[N-1][N-1][0][1]=0;
A[N-1][N-1][0][2]=-3;
A[N-1][N-1][0][3]=0;
A[N-1][N-1][1][0]=1;
A[N-1][N-1][1][1]=0;
A[N-1][N-1][1][2]=-3;
A[N-1][N-1][1][3]=0;
return 0;
}
另外,您使用一个变量来定义数组的长度,这只在C99标准和以后的标准中是好的。如果你不需要VLA(可变长度数组),你应该使用#define来代替。
int n=4;
float A[n][n][n][n];
A[n][n][1][1]=1;
并非在所有C标准中都有效(请阅读n1570或更高版本)。您可能想要编码const int n=4;
或#define n 4
(在便宜的微控制器上,你甚至可能没有足够的堆栈空间来容纳256个浮点数->可能的堆栈溢出)
然后,你总是有缓冲区溢出(阅读未定义行为)。在A[x][x][1][1]
中,有效索引从x
为0到x
为3,即n-1
-(而不是4)。
你可能想要编码
A[n-1][n-1][1][1] = 1;
但是你应该知道A[0][0][0][0]
是未初始化的。它可能包含垃圾(信令NaN),并且假设的printf("%fn", A[0][0][0][0]);
可能失败....
我猜Frama-C会发现你的错误(我让你检查)。注意Rice定理
我将用零初始化A
(以简化调试,并具有更多可重复的运行)-在纠正缓冲区溢出之后-:
float A[n][n][n][n]={0.0};