2012-06-16 5 views
1

나는이 기능을 우연히 answerthis question에 : 나는 리터럴 문자열에 대한 포인터를 반환하는 일을한다는 놀라운 사실을 발견, 그리고 내가 생각했던 것처럼 세그 폴트하지 않았다리터럴 문자열은 어디에 배치되며 왜 포인터를 반환 할 수 있습니까?

/* Note: I've formatted the code for readability. */ 
const char * getString() { 
    const char *x = "abcstring"; 
    return x; 
} 

. 저는 항상 리터럴이 스택에 밀려나거나 다른 임시 메모리를 사용한다고 가정했지만, 함수의 범위는 제한되어있었습니다. 하지만 여기서 그들은 상상했던 것보다 더 정적 인 것처럼 보입니다. 그런 다음 실행 파일 전체에 대해 전역적인 문자열 풀 (sort pool)의 일종으로 배치됩니까?

또한 함수에 매개 변수로 문자열 리터럴을 전달하면 똑같은가요? 예 :

/* Where is the string literal in this example being placed? */ 
myfunc(value1, value2, "rainbowdash"); 

나는 누군가가 내게 계몽되기를 바랍니다. 미리 감사드립니다! :)

+0

바이너리의'.data' 섹션에 저장하고 있다고 생각합니다. 코드를 배열로 변경하면 :'const char x [] = "abcstring";'문자열이 스택에 저장됩니다. – Pubby

+0

관련 항목 : http://stackoverflow.com/q/3570687/20862 –

+0

가능한 속담 : http://stackoverflow.com/questions/2589949/ – ellotheth

답변

1

이것은 ABI마다 다르지만 x86에서는 DS 레지스터가 가리키는 정적 메모리/DATA 페이지에 있습니다.

+3

** 항상 ** 정적 저장소에 있습니다. 이것은 C 언어에서 필요합니다. –

5

C에서 문자열 리터럴은 정적 저장 기간을가집니다. 리터럴 문자열 버전에서는 문자열의 저장이 다른 문자열 리터럴의 저장과 중복 수 있다는 것을 제외하고

const char * getString() { 
    static const char literal[] = "abcstring"; 
    const char *x = literal; 
    return x; 
} 

: 코드는 논리적으로 동일합니다.

3

대부분의 다른 답변에 대한 추가 정보로 컴파일러에서 생성 한 어셈블러 (예 : -S을 GCC로 전달)를보고 어떻게 저장되는지 확인할 수 있습니다. 그 자체로 파일로 기능을 퍼팅, 우리는 GCC는 기본적으로 (나는 어떤 관련이없는 물건을 삭제했습니다)를 생성 찾을 :

그래서 문자열이 .rodata 섹션에 저장됩니다
.section  .rodata 
.LC0: 
     .string "abcstring" 
     .text 

     .globl getString 
     .type getString, @function 
getString: 
     # load the address of ".LC0" which is the start of the "abcstring" 
     movl $.LC0, %eax 
     ret 

(" R ead- nly data ") 스택에 없으므로"글로벌 "주소를 가지며 항상 범위 내에 있습니다.

마찬가지로, myfunc("thisisastring")의 문자열 리터럴도 .rodata 섹션에 배치되며 스택에 없습니다.

관련 문제