1

我在回答这个问题时偶然发现了这个功能:

/* 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");

我希望有人能启发我。提前致谢!:)

4

3 回答 3

6

在 C 中,字符串文字具有静态存储持续时间。您的代码在逻辑上等同于:

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

除了在带有字符串文字的版本中,字符串的存储可能与其他字符串文字的存储重叠。

于 2012-06-16T04:11:06.123 回答
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节(“只读数据”)中,而不是堆栈中,因此它具有“全局”地址(并且始终在范围内)。

类似地,字符串字面量 inmyfunc("thisisastring")也被放入一个.rodata节中,并且不在堆栈中。

于 2012-06-16T04:20:21.347 回答
1

它因 ABI 而异,但在 x86 上,它们位于静态内存/数据页面中,由 DS 寄存器指向。

于 2012-06-16T03:24:45.380 回答