2013-02-14 3 views
1

main 안에있는 m의 첫 번째 요소에 액세스하려고하면 다음과 같은 간단한 예가 발생하면 세그먼트 화 오류가 발생합니다.이 간단한 C 예제가 세그 폴트로 끝나는 이유는 무엇입니까?

왜 이런 일이 발생합니까?

어떻게 해결할 수 있습니까? 그렇지만 코드의 전체 구조는 동일하게 유지할 수 있습니까?

감사합니다.

#include <stdio.h> 
#include <stdlib.h> 

double *array(int cols) { 
    return malloc(cols*sizeof(double)); 
} 

void create_and_modify_array(double *m) { 
    m = array(10); 
    m[0] = 123; 
} 

void main() { 
    double *m; 
    create_and_modify_array(m); 
    printf("%f\n", m[0]); 
} 
+2

당신은 main''에서'm'을 변경하지 않습니다. 'mess_around_with_matrix'의'm'은 main 안에'm'의 * copy *입니다. – dmckee

답변

6

여기서 문제는 C가 항상 값으로 전달된다는 것입니다. 값에 의한 전달은 함수 인수가 호출 된 변수의 복사본임을 의미합니다. 이 수행 할 때이 의미 :

m = array(10); 

create_and_modify_array(double *m) 내부 만 변화를 어디 m 점의 함수의 로컬 복사본. main 메서드의 m 포인터는 영향을받지 않습니다 (초기화되지 않은 상태로 유지되므로 충돌이 발생합니다). '

void create_and_modify_array(double **m) { 
    *m = array(10); // change the pointer that `m` points to 
    (*m)[0] = 123; // assign something to the first element of what `m` points to 
} 

을 그리고 main()의 주소 통과의 m 포인터의 m에서 :

이 문제를 해결하려면, 당신은 main()에 대한 포인터를 전달할 수 포인터가 생성되기 때문에

void main() { 
    double *m; // make a pointer to a double 
    create_and_modify_array(&m); // pass a pointer to the pointer to the double 
           // or, in alternative wording: 
           // pass the address of the pointer to the double 
2

create_and_modify_arraymain()에서 선언되고 사용 된 것과 다른 주소입니다. 이 대신

double *create_and_modify_array(double *m) { 
    m = array(10); 
    m[0] = 123; 
    return m; 
} 

void main() { 
    double *m = create_and_modify_array(m); 
    printf("%f\n", m[0]); 
    free (m); 
} 
1

main 내부 m가 아직 초기화되지 않은되도록 create_and_modify_array 내부 m이, 지역 변수이기 때문에이 세그먼테이션 폴트 (segfault)를 할 수 있습니다.

코드의 흐름이 더 명시하려면 main m의 시작

는 무작위 할당되지 않은 메모리 주소입니다. 그런 다음 해당 메모리 주소로 create_and_modify_array을 호출합니다. 내부 create_and_modify_array 안에 m이라는 새 변수가 생성되고 전달 된 임의의 할당되지 않은 메모리 주소가 있습니다. array을 호출하고 m 내부의 create_and_modify_array이 할당 된 메모리에 할당됩니다.

m 값이 의 m으로 절대 전달되지 않는 것이 문제입니다.

create_and_modify_array에 주의 m에 대한 포인터를 전달할 필요가 수행합니다

void create_and_modify_array (double **m) { 
    double *tmp = array(10); 
    tmp[0] = 123; 
    *m = tmp; // This passes the value of tmp back to the main function. 
       // As m in this function is actually the address of m in main 
       // this line means put tmp into the thing that is at this address 
} 

void main() { 
    double *m; 
    create_and_modify_array (&m); // This passes the address of the variable m 
            // into create_and_modify_array 
    printf ("%f\n", m[0]); 
} 
관련 문제