2011-04-25 6 views
3

nxn 행렬에 스토리지를 할당하는 함수를 작성하고 있습니다. 나는 다음과 같은 코드를 실행하면행렬에 스토리지 할당하기

void assign_matrix_storage(double **matrix, int n){ 
    if((matrix = malloc(n * sizeof(double*))) == NULL){ 
     printf("ERROR: Memory allocation failed\n"); 
     exit(EXIT_FAILURE); 
    } 

    int i; 
    for(i = 0; i < n; i++){ 
     if((matrix[i] = malloc(n * sizeof(double))) == NULL){ 
      printf("ERROR: Memory allocation failed\n"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    return; 
} 

는 그러나, 나는 마지막 문에 세그먼트 폴트를 얻을 : 왜이 ​​

double **A; 
assign_matrix_storage(A, 2); 
A[1][1] = 42; 

입니까?

+0

http://stackoverflow.com/questions/16004668/c-allocating-a-matrix-in-a-function/27366086#27366086 당신은 내가 기능을 할당하여 만든 프로그램을 찾을 수 위 C (gcc C11/C99)에 대한 가능한 모든 방법으로 행렬을 조작합니다. 어쩌면 그것은 당신에게 유용 할 것입니다 ... – 42n4

답변

3

당신은 (완벽하게) 당신의 행렬 메모리를 할당했지만 실제로 호출 수신자의 A 변수에 할당하지 않습니다. 대신 A은 아직 초기화되지 않은 채로 끝나고 A[1][1]에 할당하려고 시도하면 segfault가 발생합니다. 이를 수행하려면 해당 변수에 대한 포인터가 필요하며 행렬을 해당 주소에 할당하십시오. 효과 그래서, 함수 서명 및 구현을 변경해야합니다 :

/* take a pointer to a (double **) */ 
void assign_matrix_storage(double ***matrix, int n){ 
    /* then all accesses need to dereference first */ 
    if(((*matrix) = malloc(n * sizeof(double*))) == NULL){ 
     printf("ERROR: Memory allocation failed\n"); 
     exit(EXIT_FAILURE); 
    } 

    int i; 
    for(i = 0; i < n; i++){ 
     if(((*matrix)[i] = malloc(n * sizeof(double))) == NULL){ 
      printf("ERROR: Memory allocation failed\n"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    return; 
} 

/* then call */ 
double **A; 
assign_matrix_storage(&A, 2); 
A[1][1] = 42; 

더 나은 대안을 대신 새로운 행렬에 포인터를 반환하고 변수에 그를 할당하는 것입니다 무슨에.

double **assign_matrix_storage(int n) { 
    double **matrix; 
    /* the rest of your implementation */ 
    return matrix; 
} 

double **A; 
A = assign_matrix_storage(2); 
A[1][1] = 42; 
3

A이 (가) assign_matrix_storage()에 의해 변경되지 않기 때문에 상황이 발생합니다. C는 값에 의한 값이므로 사본 A을 전달합니다. 따라서 함수에서 A에 대한 변경 사항이 손실됩니다. 매개 변수는 double ***pointerToA과 같아야합니다. 그러면 함수를 호출 할 때 assign_matrix_storage(&A, 2); 그리고 분명히 assign_matrix_storage() 안에 pointerToA 하나의 "레벨"을 올바르게 적용해야합니다.

+1

'double ***'을 인자로 받아들이 기보다는'double **'을 반환하는 것이 더 좋을 수도 있습니다. –

+0

좋은 점! 'assign_matrix_storage()'가'int n'을 가져 와서 할당을 수행하고'double **'을 반환하게하십시오. – QuantumMechanic

1

아마도이 구현이 유용 할 수 있습니다.

/* Allocate space for a unit-off-set (m times n) matrix b[1..n][1..m] */ 
/* Note that b_{ij}=b[j][i], so the i'th column is b[i] */ 
double **matrix(int m, int n){ 
    int i; 
    double **a = (double **)malloc(n*sizeof(double *)); 
    double **b=a-1; /* make unit off-set */ 
    for (i=1; i<=n; i++) b[i] = (double *)malloc((m+1)*sizeof(double)); // m+1, not m! 
    return(b); 
}