C언어에서 포인터가 어려운 것은 알쏭달쏭한 경우가 있기 때문입니다.

자, 아래 코드를 보세요. 잘못된 점이 보이나요?


void get_value( int *ptr_val){

   *ptr_val = 100;

}


int main( void){

    int num = 0;

    int *ptr_num = #


    get_value( ptr_num);

    printf( "num= %d\n", num);


    return 0;

}


어디가 잘못 되었는지 보이시나요? 결론은 매우 자연스러운 코드로 아무 이상이 없습니다.

그렇다면 아래 코드는 어떨까요?


void get_value( int *ptr_val){


    ptr_value = malloc( sizeof( int));

   *ptr_val = 100;

}


int main( void){

    int *ptr_num;


    get_value( ptr_num);

    printf( "num= %d\n", *ptr_num);


    return 0;

}


역시 이 코드도 정상일까요? 그러나 실행해 보면 세그멘테이션 에러가 발생할 것입니다.

그렇다면 뭐가 잘못일까요? 모두 똑깥이 포인터 변수를 넘겨 주었고 위 아래 get_value() 

모두 포인터 변수를 사용했는데 말이죠.


그러나 큰 차이가 있습니다. 첫 번째의 코드는 포인터 변수가 가지고 있는 주소값을 전달하고 그 주소값을

이용했습니다. 이에 비해 두 번째 코드는 포인터 변수가 가지고 있는 주소값을 전달했는데

주소값을 전달했을 뿐 실제 포인터의 변수를 전달한 것은 아닙니다. 

주소 숫자만 전달했는데 그 숫자를 받은 포인터 변수에 malloc()으로 새로운 주소값을 대입했다고

원래 포인터인 ptr_num의 값이 변동될 수 없습니다.


문제가 있는 두 번째 예제 코드를 다시 풀어서 말씀 드리죠.


main() 함수에서 get_value()를 호출할 때 포인터 변수 ptr_num 자체를 전송한 것이 아니라 ptr_num이 가지고 있는 값을 전달했습니다.

get_value()의 ptr_val은 그 값을 전달 받았죠. 그리고 malloc()로 메모리를 생성해서 그 주소 값을 ptr_val에 대입했지만,

그렇다고 main()함수의 ptr_num의 변수 값까지 바뀌지 않습니다. 서로 전혀 다른 변수이기 때문이죠.

즉, main()함수의 ptr_num에 malloc()로 생성한 메모리의 주소값을 넣기 위해서는 포인터의 포인터 변수를 사용해야 합니다.


void get_value( int **ptr_val){


    *ptr_value = malloc( sizeof( int));

   **ptr_val = 100;

}


int main( void){

    int *ptr_num;


    get_value( &ptr_num);

    printf( "num= %d\n", *ptr_num);


    return 0;

}


이렇게 처리해야 정상적으로 처리됩니다. 변수 값이 아닌 변수 자체를 넘겨 주려는 Call By Reference 이용할 때

int num; 의 경우 &num 를 사용하는 것처럼 포인터 변수도 다른 함수에서 변수의 값을 바꾸기 위해서는 주소값을

넘겨 주어야 합니다.