С++ 中的字符串文字是在静态内存中创建的吗?

Posted

技术标签:

【中文标题】С++ 中的字符串文字是在静态内存中创建的吗?【英文标题】:Is a string literal in С++ created in static memory? 【发布时间】:2010-09-25 19:53:55 【问题描述】:

c++中的字符串字面量是在静态内存中创建的,只有在程序退出时才销毁?

【问题讨论】:

【参考方案1】:

实际上,它的创建位置是编译器编写者的实现决定。最有可能的是,字符串文字将存储在内存的只读段中,因为它们永远不会改变。

在旧的编译器时代,您曾经拥有像这些文字这样的静态数据,以及全局但可变的数据。这些存储在 TEXT(代码)段和 DATA(初始化数据)段中。

即使您有char *x = "hello"; 之类的代码,hello 字符串本身也存储在只读内存中,而变量x 在堆栈上(如果它是全局变量,则在可写内存中的其他位置)。 x 只是设置为hello 字符串的地址。这允许字符串折叠等各种棘手的事情,因此“无效选项”(0x1000)和“有效选项”(0x1002)可以使用相同的内存块,如下所示:

+-> plus:0   1   2   3   4   5   6   7   8   9   A   B   C   D   E
|      +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+
0x1000 | i | n | v | a | l | i | d |   | o | p | t | i | o | n | \0 |
       +---+---+---+---+---+---+---+---+---+---+---+---+---+---+----+

请记住,我指的不是 ROM 中的只读内存,而是专门用于存储不可更改内容的内存(操作系统可能将其标记为真正只读)。

main() 退出之前,它们也不会被销毁。

【讨论】:

BSS 段只保存过零但非常量的数据;初始化为非零值的数据位于 DATA 段中。 @Destructor,我假设这是对 JamesHopkin 答案的评论。 那是的答案,即“字符串文字在程序的整个持续时间内都有效,即使在静态对象的销毁期间也是如此”。我的回答和 unwind 的回答(您发表此评论的另一个)都没有对此提出异议,但至少您已经包围了詹姆斯 :-)【参考方案2】:

是的,字符串字面量在程序的整个过程中都有效,即使在静态对象的销毁期间也是如此。

标准中的 2.13.4/1 说

普通的字符串字面量具有“n const char 数组”类型和静态存储持续时间。

标准在 3.7.1/1 中提到“静态存储持续时间”:

这些对象的存储将持续到程序的持续时间。

【讨论】:

【参考方案3】:

嗯……是的。他们必须是;构成每个字符串中字符序列的信息必须在某个地方。如果它们被动态分配然后初始化,用于初始化的信息将驻留在哪里?因此,简单地将字符串设置为静态会更有效,以便在程序加载完成后它们始终可用且有效。

【讨论】:

【参考方案4】:

字符串字面量存储在内存的只读段中

【讨论】:

可能,但不是必需的。符合要求的实现可以将字符串文字存储在读写内存中。无论如何,任何可以区分差异的程序都有未定义的行为。当然,将它们存储在只读内存中是个好主意(如果底层系统支持的话)。

以上是关于С++ 中的字符串文字是在静态内存中创建的吗?的主要内容,如果未能解决你的问题,请参考以下文章

匹配Rust中的Option静态字符串文字[duplicate]

如何获取我在 python 中创建的字典中的值,而不是字符串?

静态变量在内存哪分配的?是栈里分配还理堆里分配的?

在 IB 中创建的静态 UILabel 显示缓慢

字符串常量池和String::intern()的讨论

字符串常量池和String::intern()的讨论