C언어는 포인터 때문에 힘들다고 푸념하시는 분이 많으십니다. 때로 포인터를 사용하지 않는 것이 좋다는 엉뚱한 주장도 있습니다만, 포인터 이해가 어렵다는 것은 옳아도, 어렵고 힘들다고 해서 사용하지 말아야 한다는 것은 동의하기 어렵습니다. 어렵기만하고 쓸모가 없다면 벌써 도태되었을 것입니다. 물론 이런 저의 생각에 반론하시는 분도 계실 것입니다. 그렇게 좋은 포인터라면 이후에 나온 자바나 4G 언어에는 왜 포인터가 없냐고 말이죠.

 

실제로도 이런 반문을 받은 적이 있습니다만, 자바나 새로 나온 언어에 포인터가 없다고 해서 포인터가 구시대적 유물이고 효용성이 떨어진다라는 말씀인데, 적잖이 당황됩니다. 자바나 4G가 C 보다 이후에 나왔다고 해서 좋은 언어라고 할 수 있을 까요? 물론 장점을 수용하면서 더 발전시켰다라고 할 수 있겠지만, 그렇다고 C 언어 보다 월등하다라고 말하는 것은 모순이 있습니다. 월들하거나, 월등하지는 않아도 더 좋은 언어가 있다면 포인터뿐만 아니라 복잡한 코드를 생산하는 C 언어는 벌써 도태되었을 것입니다.

 

자, 포인터 얘기를 꺼내니 벌써부터 내용이 어지러워 집니다. 그렇다면 왜 포인터는 아직도 어려운 주제일까요? 그것은 포인터에 대한 이해가 부족했기 때문 보다는 실수할 수 있는 경우의 수가 많기 때문입니다. 즉, 포인터 개념이 문제가 아니라 개발자가 실수하기가 쉽기 때문에 아직도 어려운 주제라고 생각합니다..

 

예를 들어 볼까요? 매우 간단한 예입니다. 어디가 틀렸을까요?

 

#include <stdio.h>

int main( void){

    char *name  = "jang Kilseok";
                        
    name[0] = 'J';                        
                        
    printf( "%s\n", name);

    return 0;
}

 

컴파일하면 아무 에러 없이 실행 파일이 만들어 집니다. 실행해 봅니다. 그런데 아래와 같이 중지되어 버립니다. 문제는 에러 내용이 매우 친절하지 못합니다.

 

]$ ./a.out
세그멘테이션 오류
]$

 

뭐냐? 빌드 과정에서 아무 문제 없었는데 실행만 하면 이꼴이네. 그런데 황당하게 "세그멘테이션 오류"라고만 하니 어쩌라고? MS 윈도우에서 마찬가지입니다.

 

 

자세한 정보를 보여 주지만, 불친절하기는 마찬가지 입니다. 이래서 입문자에게는 C 언어가, 특히 포인터가 어렵게 느낄 수 밖에 없습니다. 책 내용을 다시 보아도 틀린 것이 없는데, 컴파일해도 아무 에러 메시지가 없는데, 실행이 안 되니 답답할 수 밖에요.

 

자, 그렇다면 뭐가 문제일까요? 문제는 char *name에 대입되는 "jang Kilseok" 문자열이 데이터 영역이 아닌 코드 영역에 있기 때문입니다. 잠시 생각해 보시면 아시겠습니다만, char *name은 포인터로 "jang Kilseok"의 모든 문자열을 담은 그런 변수가 아닙니다. 대신에 문자열의 시작인 'j' 가 위치한 주소 값을 name에 넣어 지게 됩니다.

 

여기까지는 아무런 문제가 없습니다. 프로그램 소스에 "jang Kilseok" 가 있으므로, 만들어진 실행 파일 어디에는 반드시 "jang Kilseok"가 있고, 프로그램이 실행되면 프로그램 코드 영역에 "jang Kilseok"가 들어 가게 됩니다. 그리고 그 문자열 선두 주소가 name 변수에 들어 가구요. 이해되시죠?

 

문제는 그 다음에 있습니다. name[0] = 'J' 가 그렇습니다. 이는 *name = 'J'와 같은 얘기인데, "jang Kilseok" 문자열의 첫 번째 문자를 'J'로 바꾸라는 얘기입니다. 생각해 보면 문제 없을 것 같은데, 실은 심각한 문제가 있습니다. 다시 말씀드리지만, "jang Kilseok" 문자열은 데이터 영역이 아니라 코드 영역에 있습니다. 즉, 프로그램의 실행된 코드 내용을 변경하겠다는 것으로 코드 영역을 읽을 수는 있어도 쓰기할 수 없는 영역이기 때문에 실행할 수 없고, 실행할 수 없기 때문에 종료될 수 밖에 없습니다.

 

자, 여기서 잠시 정리해 보죠. 지금 포인터를 사용했기 때문에 실행 에러가 발생했지만, 포인터를 문법적으로 잘못 사용하지 않았습니다. 그래서 컴파일 오류도 발생하지 않았지요. 그래서 포인터를 이해하기 위해서는 위와 같은 코드 영역이니 데이터 영역이니 프로그램 실행되는 시스템도 이해를 필요로 합니다. 포인터 입장에서는 억울한 일이겠습니다만, 어쨌거나 포인터가 없는 언어에서는, 또는 포인터를 사용하지 않으면 이런거 신경쓰지 않아도 저런 실행 에러가 발생되지 않습니다.

 

그렇다면 문제를 어떻게 해결해야 하나요? 간단히 해결할 수 있습니다. char *name를 char name[]로 변경하면 바로 해결됩니다.

    char *name  = "jang Kilseok";
를    
    char name[]  = "jang Kilseok";

 

왜 일까요? 이 이유는 다음 시간에 말씀 드리겠습니다.