2011-09-17 3 views
1

우리가이 코드 조각을 실행하면 화면에 정상적으로 인쇄 string constant 작동합니다이 경우 char []와 char *가 어떻게 다른가요?

char *someFun(){ 
    char *temp = "string constant"; 
    return temp; 
} 
int main(){ 
    puts(someFun()); 
} 

을하지만 우리는 다음과 유사한 코드를 실행하면, 작동 및 화면에 약간의 쓰레기를 인쇄하지 않습니다

char *someFun1(){ 
    char temp[ ] = "string"; 
    return temp; 
} 
int main(){ 
    puts(someFun1()); 
} 

이유가 무엇입니까? 본질적으로 두 함수 모두 비슷한 일을하지만 (즉, "문자열"을 반환), 여전히 다르게 작동합니다. 왜 그런가요?

답변

5
char *temp = "string constant"; 

string constant 리터럴은 읽기 전용 세그먼트에 있습니다. 프로그램 종료시 할당이 해제됩니다. 그래서, 당신은 그것을 가리키는 참조를 가질 수 있습니다.

char temp[ ] = "string"; 

string는 스택에 상주 temp에 복사된다. 함수가 반환 될 때 함수 범위의 변수를 할당 해제하는 스택 해제가 시작됩니다. 하지만 스택에 더 이상 존재하지 않는 참조를 반환하고 따라서 당신은 쓰레기를 받고 있습니다. 그러나 때때로 당신은 여전히 ​​정확한 결과를 얻을 수 있지만 그것에 의지해서는 안됩니다.

+1

'someFun1()'에서 지역 변수 (배열)가 이전에 사용한 공간을 사용하여 리턴 주소와 프레임 포인터와 같은 제어 정보와'puts()'의 지역 변수를 사용할 수 있습니다. –

+2

덧붙여 말하면, 문자열 리터럴을 처리 할 때 문제가 발생하지 않도록하려면 const char * 변수 안에 포인터를 저장해야합니다. 따라서 컴파일러가 수정하려고하면 차단합니다. –

3

첫 번째 경우 포인터 temp"string constant"을 저장하는 전역 상수를 가리 킵니다. 따라서 포인터를 반환하면 유효합니다.

두 번째 경우 'string' '은 스택의 char 배열이며 함수에서 돌아온 후에 종료됩니다.

+0

첫 번째 경우 전역 힙에 저장되고 두 번째 경우 로컬 스택에 저장되는 이유는 무엇입니까? – buch11

+2

기본적으로 문자열 리터럴은 전역으로 저장됩니다. (힙에는 없지만 프로그램 메모리에 있음) 그러나 char []를 선언하면'{ 's', 't', 'r'}에 대한 짧은 형식으로 문자열을 넣을 수 있습니다. 'i', 'n', 'g'} '. – Mysticial

+0

... 널 종결 자 포함. –