2016-12-08 4 views
1

Я написал программу ниже ti реализует алгоритм с большими массивами, но когда N превышает 820, у меня проблема с сегментацией (ядро) из-за памяти. Я использую 3 больших массива для реализации моего кода. Как я могу исправить эту ошибку?недостаток памяти в программе C

#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

определяется три матрицы и три вектора в стеке. Вероятно, переполнение стека происходит, когда 'N' велико. Вы можете попытаться распределить большие массивы динамически в куче с помощью 'malloc'. –

+0

ошибка сегментации происходит от функции 'main', где вы объявляете массивы. Эти переменные объявляются в стеке, которое является ограниченным пространством ('ulimit -a' в командной строке для размера пространства стека, если вы используете linux/unix, обычно 4k или 8k), если ваши переменные превышают этот размер, тогда вы собираетесь должны динамически выделять пространство или увеличивать размер стека с помощью 'ulimit -s' и видеть, что это« толкает »предел вашего кода на более высокий« N ». В противном случае используйте 'malloc' для явного выделения памяти –

ответ

1

Вы выделяете большие матрицы в стеке в main. Когда N составляет 840, для каждой матрицы требуется около 2,8 МБ. Ваш стек не может вместить эти матрицы, и он переполняется.

Вы можете подделать с настройками стека вашей системы, но, как правило, лучше выделить большие матрицы и векторы на куче:

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); 
0

Ошибка сегментации связана с переполнением стека. Вместо этого вы можете использовать кучу. Простым способом использования кучи является объявление ваших массивов в глобальной области.

Обратитесь к этому ответу на явно используя кучи: https://stackoverflow.com/a/571961/2791719

Смежные вопросы