오늘은 간단하게 문자열 리터럴만 올리도록 하겠습니다. "chogahui", "xi" 이런 것들을 우리는 리터럴이라고 합니다. 그러면, 이것들은 어디에 어떻게 저장이 되길래, 이들을 바꾸려고 하면 RTE가 뜰까요?

 

 


 예제 프로그램 1을 봅시다.  4번째 줄에 보면 "chogahui" 라는 리터럴이 있습니다. 이것을 p가 가리키고 있어요. 그리고 p[0]에 'x'를 넣습니다. 6번째 줄에 p를 출력하는데요. "xhogahui"라는 내용이 출력될 거 같아요.

 

 

 그런데, Seg fault가 뜹니다. 어떻게 된 걸까요? 이 상황을 다시 그려봅시다.

 

 

 p가 "chogahui"를 가리키고 있어요.

 

 

 그러면 p[0]은 "chogahui"의 1번째 요소인 'c'일 겁니다. 이것을 'x'로 바꾸는 연산은, 메모리의 어느 영역에 'x'라는 값으로 write를 하는 것입니다. 물론, Read, Write가 가능한 영역이면 이것은 큰 문제가 되지는 않습니다.

 

 

 그런데, 이것이 Read Only 영역에 들어가 있으면 문제가 발생합니다. 읽기만 가능한 영역인데 쓰기를 시도했기 때문입니다. N1548 문서의 86페이지에 따르면 "abcd" 이런 식으로 선언한 경우, 항상 'static storage duration'을 가진다고 되어 있어요. 다만, 이것이 .rdata에 할당되는지, 읽기만 가능한 영역에만 생성이 되는지는, 언급이 되어 있지 않습니다.

 

 C11 표준에 따르면, 5번째 줄과 같이 리터럴을 수정하려고 시도하면 undefined behavior라고 되어 있습니다. 운이 좋게도, 쓸 수 있는 곳에 리터럴이 생성되었다면, 수정을 해도 별 문제가 없을 겁니다. 그렇지 않다면 access 위반이고요. 어떤 상황이 벌어질 지 알 수 없다는 의미입니다.

 

 

 그러면 strcat 함수를 사용한 경우는 어떨까요? 마찬가지입니다. 이것은 "chogahui" 뒤에 "05"를 붙이겠다는 의미인데요. 중요한 것은 "chogahui"가 문자열 리터럴입니다.

 

 

 만약에 이것이 읽기만 가능한 영역에 들어있다면 어떨까요? 인접한 영역도 모두 다 Read only라면. 당연하게도, "05"를 뒤에 붙인다면, 노란색 영역에 데이터를 write 하기 때문에 access 위반이 됩니다. 리터럴에 write 하는 상황과 똑같은 상황이 벌어지고 있는 셈입니다. 행동이 정의되지 않습니다.

 

 


 그러면 아래와 같은 경우에는 어떨까요?

 

 

 이렇게 선언한 경우, 아래와 똑같은 의미를 가집니다.

 

 단지, char형 10개를 넣기 위한 공간을 stack에다가 생성하고, 'c', 'h', ... , 'i'를 넣은 것 뿐입니다.

 

 

 그러면, 이 경우, stack 영역에 'c', 'h', ... , 'i'와 NULL 문자가 들어가 있을 겁니다. 우리가 지역 변수 a, b를 main 함수에 선언했을 때, a의 값을 바꿀 수 있습니다. 이는 a와 b가 할당되어 있는 메모리 영역이, Write가 가능한 영역이기 때문입니다.