Create TOC

2003년 5월 15일

char *과 char []의 차이

아래와 같은 소스가 있을때

void foo()
{
	char *pHello = "Hello, World";
	char aryHello[] = "Hello, World";
}

"Hello, World" 문자열은 data segment에 잡히고 pHello, aryHello 는 stack에 잡힌다.(전역변수라면 BSSThe portion of a program that is to be initialized to zero at the time the program is loaded into memory. The name bss is an abbreviation for "block started by symbol".)

약간의 차이점이 있는데

pHello는 data segment 에 저장된 "Hello, World" 의 메모리 주소를 pointing 하지만 aryHello 경우 "Hello, World"를 pointing 하는 것이 아니라 data segment에 잡힌 "Hello, World"를 복사한 복사본을 가지게 된다(배열을 초기화 하는 것이기 때문).

그런데 여기에 사용된 "Hello, World" 류의 상수처럼 사용되는 문자열은 string literal 라고 불리우며 ISO C 규약에 따르면 동일한 string literal 은 같은 메모리를 공유하도록 정하고 있다(메모리의 내용을 바꿀 수는 있지만 바꾸지 않는 것을 권장한다). 즉 동일 문자열 상수를 여러번 사용한다고 해서 메모리를 많이 사용하지 않는다. VC나 GCC 는 이런 string literal을 rodata(read only data) segment에 별도로 관리해서 메모리의 내용을 변경하려고 할때 에러를 발생시킨다. (gcc 경우 -fwritable-strings 옵션을 사용하면 rodata 에 관리하지 않기 때문에 에러가 발생하지 않는다). VC에서 /ZI 옵션을 주지 않고 빌드한 경우 위 내용이 적용되지 않는다. 보통 /ZI 옵션은 Debug 빌드에서 사용하기 때문에 Release 빌드에서는 /GF 옵션을 줘야 string literal에 대한 read only 처리가 된다.

그렇기 때문에 *(pHello + 1) = 'c' 와 같은 문법을 사용할 수 없다.