본문 바로가기
Engineering/C/C++

오묘한 포인터와 배열의 세계

by Humaneer 2009. 5. 25.

눈컴파일 및 실시간 두뇌 실행을 해봅시다.



거두절미 하고 아래의 소스는 과연 실행이 잘 될까?


당연히 잘 된다. Abc라는 문자열이 화면에 출력된다.



그렇다면 아래의 소스는 실행이 잘 될까? ㅋ


당연히 잘 될까? 컴파일, 링킹까지는 된다. 하지만 실행시 오류가 난다. 즉, 우리 프로그래머들이 가장 싫어하는 Runtime Error(혹은 Segmentation Fault)가 뜬다는 말이다. -_-;



그렇다면 아래의 소스는?


실행된다. abc라는 문자열이 화면에 출력된다.


도대체 뭐가 문제일까?


나도 명확하게는 잘 모르겠다. 위의 사례로 보아 배열로 선언하여 정적으로 할당받은 메모리 영역은 read/write 모두 가능하다. 하지만 포인터로 선언하여 정적으로 할당받은 메모리 영역은 read only이다. 이게 당최 뭐람? ㅋ

게다가 두번째 소스를 visual studio에서 debug mode로 컴파일을 하면 런타임 에러가 뜬다. 그런데 release mode로 컴파일을 하면 런타임 에러가 뜨지 않는다. 그렇다면 debug/release의 선택에 따라 할당하는 메모리의 영역에 차이가 있는 것인가?

정답은 '아니오'이다. release mode로 컴파일 하고 실행하면 에러는 뜨지 않는다. 즉 char* str = "abc"; str[0] = 'A' 또는 *(str + 0) = 'A'를 수행할 때 에러를 내지 않는다는 것이다. 하지만 출력해보면 그 결과가 매우 신기하다. Abc가 아니라 abc가 출력된다는 것. 즉 포인터로 할당한 문자열의 내용을 바꾸는 명령이 반영이 되지 않은 것이다.

그렇다면 결론은 이러한 것인가? ㅋ (내멋데로 결론)
char* str = "ABC"; 이렇게 포인터를 통해 정적으로 할당받은 메모리 영역은 read only이다.(배열은 read/write가능) 또한 debug mode로 컴파일을 하면 포인터를 통해 할당받은 메모리 영역에 쓰기를 시도할 때 런타임 에러를 내지만, release mode로 컴파일을 하면 에러를 내지는 않지만, write하는 명령을 무시한다.

gcc, bcc, turbo c 같은 컴파일러는 어떠한지 궁금하다. 혹시 이 글 보고 해보실 분은 해보시고 결과를 피드백해주시면 매우 감사하겠습니다 ;). 어쨌거나 오묘한 포인터와 배열의 세계. ㅋ