관리 메뉴

Humaneer.net

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

Engineering/C/C++

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

Humaneer 2009.05.25 15:58

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



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


당연히 잘 된다. 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 같은 컴파일러는 어떠한지 궁금하다. 혹시 이 글 보고 해보실 분은 해보시고 결과를 피드백해주시면 매우 감사하겠습니다 ;). 어쨌거나 오묘한 포인터와 배열의 세계. ㅋ

3 Comments
  • 프로필사진 Favicon of http://shinlucky.tistory.com BlogIcon shinlucky 2009.05.27 19:11 신고 여기저기 돌아다니다가 들렸네요 ^_^
    위 문자열 상수 관련부분에 대해 살짝 끄적일께요.
    char *p="ABC"
    라고 선언하신다면, 여기서 문자열 "ABC"는 text영역이라고 Read Only 영역에 저장이 됩니다.
    말그대로 읽기만 가능한 것이지요.
    그러나 char p[]="ABC"라고 선언하신다면
    text영역이 아닌 Stack 아니면 DATA 영역에 자리잡게 됩니다. (두개의 구분은 {}안에 선언되느냐 밖에 선언되느냐)
    Stack이나 DATA영역에 메모리가 할당된다면 Read/Write영역이기 때문에 쓰고 지울 수 있습니다.
    (님이 테스트해보신 것처럼)

    이와 관련해서 약간 어셈블리가 가미된 Memory Map쪽을 같이 공부하시면 이해가 빠를 듯 합니다.

    참고로 컴파일시 에러가 안나올때가 있습니다.
    이 경우는 컴파일러마다 약간 다르게 취급하기 때문입니다.
    하지만 보통 윈도우 기반으로 테스트를 하시면 접근이 불가능해서 런타임 에러가나고
    임베디드 쪽 보드에서 테스트를 하시면 에러는 나지 않으나 결과는 수정되지 않습니다.
    (님이 release Mode로 해보신 것처럼)

    text/data/bss/heap/stack 영역에 대해 더 찾아보시고, 공부하시면 아마 C나 기타 언어에 대해
    더 쉽게 이해하실 수 있을 꺼에요.

    뭐, 한마디로 마지막에 요약하신 결론이 얼추 맞네요 ㅋ

    그럼 수고하세요~!
  • 프로필사진 Favicon of http://humaneer.net BlogIcon Humaneer 2009.05.27 19:25 신고 우엇~ 그렇군요! text영역과 data영역의 차이였군요!

    메모리영역은 이미 배웠는데도, 아둔한 두뇌가 그쪽으로 응용을 못시켰네요. ㅋ

    설명 감사드립니다.

    :-)
  • 프로필사진 Favicon of http://www.sayong.kr BlogIcon SaYong 2009.06.03 10:21 신고 저도 한 수 배웠네요!! ^^ 요즘 컴파일러에서 배우는 부분이군요!! ㅎㅎ
댓글쓰기 폼