2012-06-16 15 views
1

我偶然发现了这个功能的answerthis question字符串放置在哪里,为什么我可以返回指向它们的指针?

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

我很惊讶地发现,一个指针返回文本字符串的工作,并没有像段错误我想的那样。我总是认为文字被推入堆栈或放入其他一些临时存储器中,但只限于函数的作用域。但在这里,它似乎比我想象的更加静态。然后他们被放入某种类型的字符串池,这对整个可执行文件是全局的吗?

此外,如果我将字符串文字作为参数传递给函数,它是一样的吗?例如:

/* 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基本上生成(我已经删除了一些无关紧要的东西):

.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 

因此字符串存储在.rodata节(” [R ead- Ø nly data“),而不是在堆栈上,因此它有一个”全局“地址(并且始终在范围内)。

类似地,在字符串中myfunc("thisisastring")字面也放入.rodata部,并且不是在堆栈中。

相关问题