我编写了下面的程序,实现了一个带有大数组的算法,但是当N超过820时,由于内存,我有一个分段错误问题(核心转储)。我使用3个大数组来实现我的代码。我该如何解决这个错误?
#define N 400
void upper(float A[N][N], float x[N], float b[N])
{
int i,j;
float sum;
x[N-1] = b[N-1]/A[N-1][N-1];
for(i=N-2; i>=0; i--){
sum = b[i];
for(j=i+1; j<N; j++){
sum = sum - x[j]*A[i][j];
}
x[i] = sum /A[i][i];
}
}
void lower(float A[N][N], float x[N], float b[N])
{
int i,j;
float sum;
x[0] = b[0]/A[0][0];
for(i=1; i<N; i++){
sum = b[i];
for(j=0; j<i; j++){
sum = sum - x[j]*A[i][j];
}
x[i] = sum /A[i][i];
}
}
void cholesky(float A[N][N],float L[N][N])
{
int i,j,k;
float sum;
for(i=0; i<N; i++){
for(j=i-4; j<i; j++){ //j-4 because i have 0 and i want to do less computations
if(j<0)
continue;
sum = A[i][j];
for(k=i-4; k<i; k++){
if(k>=0)
sum = sum - L[i][k]*L[j][k];
}
L[i][j] = sum /L[j][j];
}
sum = A[i][i];
for(k=i-4; k<i; k++){
if(k>=0)
sum = sum - L[i][k]*L[i][k];
}
L[i][i] = sqrt(sum);
}
}
void transpose(float L[N][N], float LT[N][N])
{
int i,j;
for(i=0; i<N; i++){
for(j=0; j<N; j++){
LT[i][j] = L[j][i];
}
}
}
void table(float A[N][N], float aii, float aone, float athree)
{
int i,j;
for(i=0; i<N; i++){
for(j=0; j<N; j++){
if(i==j){
A[i][j] = aii;
}
else if((i+1 ==j) || (i-1==j)){
A[i][j] = aone;
}
else if(i+3==j || i-3==j){
A[i][j] = athree;
}
else{
A[i][j] = 0;
}
}
}
}
void vector(float b[N], float b1, float b2, float all)
{
int i;
for(i=0; i<N; i++){
b[i] = all;
}
b[0] = b[N-1] = b1;
b[1] = b[N-2] = b2;
b[2] = b[N-3] = b2;
}
int main()
{
float A[N][N];
float L[N][N],LT[N][N];
float x[N];
float y[N];
float b[N];
int i,j;
table(A,12,-5,1);
vector(b,4,-1,0);
table(L,0,0,0);
cholesky(A,L);
transpose(L,LT);
lower(L,y,b);
upper(LT,x,y);
for(i=0; i<N; i++){
printf("%f\n",x[i]);
}
}
答案 0 :(得分:1)
您在main
中的堆栈上分配大型矩阵。当N
为840时,每个矩阵需要大约2.8 MB。您的堆栈无法容纳这些矩阵并且它会溢出。
您可以篡改系统的堆栈设置,但通常最好在堆上分配大型矩阵和向量:
float (*A)[N] = malloc(N * sizeof(*A));
float (*L)[N] = malloc(N * sizeof(*L));
float (*LT)[N] = malloc(N * sizeof(*LT));
float *x = malloc(N * sizeof(*x));
float *y = malloc(N * sizeof(*y));
float *b = malloc(N * sizeof(*b));
确保在使用之前已正确分配所有阵列:
if ((A && L && LT && x && y && b) == 0) {
fprintf(stderr, "Allocation failed.\n");
exit(1);
}
在main
结尾处使用资源后,请不要忘记清理资源:
free(A);
free(L);
free(LT);
free(x);
free(y);
free(b);
答案 1 :(得分:0)
您的分段错误是由堆栈溢出引起的。您可以改用堆。使用堆的一种简单方法是在全局范围内声明数组。
,请参阅此答案