C程序缺乏内存

时间:2016-12-08 14:36:21

标签: c algorithm segmentation-fault

我编写了下面的程序,实现了一个带有大数组的算法,但是当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]);
    }
}

2 个答案:

答案 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)

您的分段错误是由堆栈溢出引起的。您可以改用堆。使用堆的一种简单方法是在全局范围内声明数组。

明确使用堆:https://stackoverflow.com/a/571961/2791719

,请参阅此答案