반응형
char str[] = "abc";
char *str = "abc";
printf("%s", str) 하면 똑같이 abc가 찍혀나오니깐 별 차이가 없다고 생각할 수도 있겠지만 이 두 선언은 엄연히 다르다. 위 코드를 gcc -S 옵션으로 어셈블리로 생성해보면 두 코드 모두 "abc"를 .rodata 섹션에 할당한다,
gcc2_compiled.:
.section .rodata
.LC0:
.byte 0x61,0x62,0x63,0x0
.section .rodata
.LC0:
.byte 0x61,0x62,0x63,0x0
여기서 .rodata는 읽기 전용(read only) 데이터를 말한다. 그렇다면 다음과 같은 코드를 실행하면 어떻게 될까?
int main()
{
char *str = "abc";
str[0] = 'b';
}
{
char *str = "abc";
str[0] = 'b';
}
str은 .rodata 영역에 있는 "abc"에 대한 포인터이므로 이 값을 바꾸려고 하면 다음과 같이 오류가 발생한다.
./a.out
Bus error (core dumped)
Bus error (core dumped)
str[]의 경우는 어떨까?
int main()
{
char str[] = "abc";
str[0] = 'b';
}
{
char str[] = "abc";
str[0] = 'b';
}
이 프로그램은 문제없이 수행되며 str을 출력해보면 "bbc"가 나온다. 이런 차이가 나는 이유는 str[]의 경우 함수 호출 시에 .rodata의 "abc" 문자열을 함수의 스택으로 복사해오기 때문이다.
또 하나의 차이점이 있는데, char *의 경우 포인터 변수를 할당하여 주소 값을 가지고 있는데 비해 char[]의 경우 str 그 자체가 주소값이 된다.
[출처] char []와 char * 차이점|작성자 엥겔로
반응형