文字字符串被放置在哪里,我为什么可以返回指向他们?(Where are literal string

2019-07-29 23:29发布

我偶然发现在这个函数的回答到这个问题 :

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

我希望有人能赐教。 提前致谢! :)

Answer 1:

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

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

与在字符串文字的版本,该字符串的存储可以与其他字符串常量的存储重叠例外。



Answer 2:

作为附录大多数其他的答案,你可以看看编译器生成汇编(例如,通过传递-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- 唯一一句数据”),而不是在栈,所以它有一个‘全局’地址(而总是在范围内)。

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



Answer 3:

它每ABI不尽相同,但在x86他们在静态存储器/数据页,指向DS注册。



文章来源: Where are literal strings placed and why can I return pointers to them?