const char* 의 데이터 저장 구조

조회수 830회
const char* name = "string";
cout << &name;
cout << static_cast<const void*(&*name);

여기서 포인터 name의 주소는 실행할 때마다 변하는데

name이 가리키는 주소( 문자 s가 저장된 곳 )는 주소가 유지되는 모습을 보였습니다.

그리고 "string"을 다른 문자열로 바꾸었을 때 포인터가 가리키는 주소가 변경되었습니다.

왜 이런 구조를 보이나요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 테스트한 os가 무엇인가요?

    바이너리 포맷을 보면 섹션들로 나뉘어져 있습니다.

    질문한 것들을 이해하려면 몇가지 알아야 할 것들이 있습니다.

    현재 사용되는 os는 보호모드에서 동작하고 있고 보호모드라는 것은 가상주소모드라고도 합니다. 즉 32비트 운영체제에서 프로세스가 하나 생성되면 커널영역 2기가 유저영역 2기가를 할당받아 총 4기가를 사용하게 됩니다.

    여기서 커널영역은 물리 메모리와 1대1의 관계를 갖지만 유저영역은 가상영역으로 1대n의 관계를 갖습니다.

    예를들어 메모장을 두개 띄워서 메모리 값을 확인시 같은 메모리 주소라도 값은 다르다는 이야깁니다.

    커널영역은 같지만 유저영역은 각각 독립적이다라고 이해하면 됩니다.

    이러한 형태이기 때문에 어플리케이션이 응답이 없거나 메모리 오류가 발생해도 그 프로세스만 종료시키면 os는 아무런 문제가 없습니다만...커널영역에서의 문제. 예를들어 드라이버 충돌등으로 오류가 나면 블루스크린이 나타나게 되고 os를 종료해야 합니다.

    이제 본질문인 heap 공간의 값이 왜 같은지...여부 윈도우 바이너리 포맷인 pe format 을 보면 섹션이라는 공간의 정의가 여럿 있습니다.

    exe 파일을 실행하면 pe loader 는 그 섹션정보에 따라 메모리를 확보하고 프로그램은 수행하면서 변수등을 저장하게 됩니다.

    코드가 저장되는 .text 섹션 데이터가 저정되는 .rdata .data 등등의 섹션

    여기서 .rdata 섹션은 초기화된 상수(읽기전용)들이 저정되는 섹션입니다.

    여기서 문자열은 읽기전용 상수라는 것이고 .rdata 섹션에 저장이 되며 문자열을 수정을 하면 문자열은 읽기전용이므로 새로이 공간을 확보하여 새롭게 저장하게 되는 것입니다. 즉 문자열은 수정이 없고 새로 등록이기 때문에 메모리 주소는 변경됩니다.

    그리고 매번 실행해도 문자열 변수 주소가 같은 것은 섹션의 주소를 확인해보면 됩니다.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)