티스토리 뷰

문자열 상수, 문자배열에 대한 이해

C언어 문자 배열을 보다가 생각난 김에 정리해 놓습니다. 다음의 두 코드 char *test = "abcdef"; 와 char test[] = "abcdef";의 차이점은 무얼까요?


배열과 포인터 그리고 메모리

두 가지의 차이를 이야기 하기에 앞서서 "abcdef"에 대해 짚고 넘어갑시다. "abcdef"란 코드는 컴퓨터가 프로그램을 메모리에 로드할 때 읽기 전용 메모리에 로드되는 문자열 상수입니다. 문자열 상수의 주소란 말이죠. 참고로 읽기 전용 메모리에는 프로그램 코드 라던가 상수가 로드 됩니다. 그럼 돌아와서 문자열 상수 주소를 char *test인 포인터에 넣느냐 아니면 char test[]인 배열에 넣느냐가 차이점 이군요. 둘의 차이는 다음과 같습니다. 


1. char *test = "abcdef";  -  포인터에 문자열 상수를 할당합니다. 따라서 문자열을 참조 할 수는 있지만 값을 바꾸지는 못합니다. 문자열이 저장된 메모리가 읽기 전용 메모리 라서 그렇습니다. 즉 test[2] = 'x'; 구문 처럼 쓰면 에러가 발생합니다. test 변수가 가리키는 문자열이 읽기전용이기 때문입니다.

2. char test[] = "abcdef";  -  문자 배열을 문자열 상수의 크기 만큼 스택에 할당하고 그 내용도 동일하게 복사합니다. 메모리 상에는 2개의 "abcdef"가 있게되겠군요. 하나는 읽기 전용 메모리에~ 다른 하나는 스택에~ 이제 test[2] = 'x'와 같이 배열에 있는 값을 변경할 수 있습니다.


메모리는 스택, 힙, 전역 메모리, 읽기전용 메모리 (상수 + 코드)로 이뤄집니다. 


정리

문자열 상수를 가리키는 포인터는 그 값을 변경할 수 없다. 대신 문자열 상수로 초기화 한 배열은 사본이 배열에 복사 되므로 변경할 수 있다.