https://stackoverflow.com/questions/7943628/where-will-a-constant-string-be-stored-in-memory


1. char * szA = "abc"; 

이때의 "abc"는 const char 문자열 상수로 DATA에 저장된다. 즉 static과 같은 느낌으로 프로그램과 라이프타임을 같이 한다.


2. char szB[] = "abc";

이 때의 "abc"는 배열 szB[]의 초기화리스트로 사용되어 STACK에 할당된다. 라이프타임은 함수와 함께한다.

 함수안에서 위와같이 작성하고 return szB를 받으면 컴파일러가 경고하는 걸 볼 수 있다. 


char* foo()

{

char szA[] = "hello A\n";

return szA;

}

char* foo2()

{

char* szB = "hello B\n";

return szB;

}

int main()

{

cout << foo() << endl; //Warning C4172 returning address of local variable or temporary: szA

cout << foo2() << endl;; //ok

}


결과:

먿

hello B


그런데 위를 작성하다가 궁금한 것이 생겼다.


"그럼 

while(1억번)

{

cout << "안녕\n"; 

}

처럼 문자열 리터럴을 마구 쓰다간 DATA 메모리가 남아나지 않겠는걸?"


그래서 확인을 해봤다.

char* testA(char arr[])

{

return arr;

}

char* testB(char* arr)

{

return arr;

}

void main()

{

static const int a = 3;

static const int b = 4;

static const int c = 5;

cout << int (&a) << endl <<int(&b) << endl << int(&c) << endl;

cout << "---------------------------\n";

cout << int(testA("abcdef")) << endl;

cout << int(testA("bbcdef")) << endl;

cout << "---------------------------\n";

cout << int(testB("abcdef")) << endl;

cout << int(testB("bbcdef")) << endl;

cout << "---------------------------\n";

char* cha = "abcdef";

cout << int(cha);

}


결과:


위 static const int 변수 세개의 주소는 그냥 호기심차원에서 문자열 상수 "abcdefg"가 static const와 같은 영역에 속하는지 알아보기 위함이다.

그리고 신기한건 testA를 통해 들어간 "abcdef"와 testB를 통해 들어간 "abcdef"가 같은 주소를 가진다는 것이다.

또 맨 아래에서 cha에 대입한 "abcdef"의 주소도 같다. 


이를 통해 알 수 있는건 컴파일러가 이미 해당 문자열이 나왔었는지 체크하기 때문에 그 주소를 프로그래머가 추적하고 있지 않아도 된다는 것이다. 어떻게 이런일이? 궁금해서 직접 스택 오버플로우에 물어봄 

https://stackoverflow.com/questions/48849365/how-does-compiler-knows-the-string-literalconst-char-already-exist-in-data-me


1. 문자열 리터럴은 간혹 static으로 되어 한번만 할당됨. 즉 위의 루프의 할당은 한번만 발생

2. 위의 리터럴의 주소가 같은 건 100% 항상 그런 것이 아님. 그럴수도 있고 아닐 수도 있고. 컴파일러의 성능에 따라 달라짐

3. sizeof("Hello")나 "Hello"[2], p = "Hello" 같은건 굳이 데이터에 올리지 않고도 컴파일러가 처리함. (레지스터를 사용하기 때문일까?)