【问题标题】:Lifetime of a string literal returned by a function函数返回的字符串文字的生命周期
【发布时间】:2011-02-04 12:16:05
【问题描述】:

考虑这段代码:

const char* someFun() {
    // ... some stuff
    return "Some text!!"
}

int main()
{
   { // Block: A
      const char* retStr = someFun();
      // use retStr
   }
}

在函数someFun() 中,"Some text!!" 存储在哪里(我认为它可能在 ROM 的某个静态区域中)以及它的 scope 生命周期是多少?

retStr指向的内存会在整个程序中被占用还是在A块退出后被释放?

【问题讨论】:

标签: c++ c lifetime string-literals


【解决方案1】:

字符串将静态存储在程序二进制文件的特殊(在现代操作系统上通常为只读)部分。它的内存没有被分配(单独为字符串,仅在将其加载到内存时用于整个部分)并且不会被释放。

【讨论】:

  • 这不一定是真的。如果您链接的二进制格式不支持“只读部分”的概念怎么办? (例如最基本的 COM 文件)
  • mamonts 也没有只读部分。他们只有历史意义。
  • 即使在 com 文件中,也会有一些部分(文件的部分)或几个部分用于存储常量。它们不会在段或页面描述符中被标记为只读,但想法是一样的。
  • 这只是一个极端的例子,不可能将字符串放入“只读部分”(因为没有部分)。关键是这是不可能的,标准没有强加这样的要求,因此一个符合要求的编译器/链接器可能不会这样做,即使有可能
  • 关于 COM 文件,您绝对错了:COM 文件是实模式“内存快照”,甚至是 逻辑上链接器放置的所有常量都不是只读的。 实模式没有任何那种内存保护功能。
【解决方案2】:

retStr指向的内存会在整个程序中被占用还是在A块退出后被释放?

编辑:

它将发布,但retStr 将不可用。 (块范围)

const char *ptr;
{   
   const char* retStr = "Scope";
   ptr = retStr;
}   

printf("%s\n", ptr); //prints "Scope"

//printf("%s\n", retStr); //will throw error "retStr undeclared"

【讨论】:

  • 不会发布,只有符号 retStr 不可用
  • 不正确。 retStr 执行后指向的内存是静态内存。它在应用程序启动时分配,仅在应用程序终止时(有效)释放。
  • @all:我的错,我在想retStr。会改变答案。
【解决方案3】:

"Some text!!" 没有作用域Scopenamed 实体的属性。更准确地说,它是名称本身的属性。 "Some text!!" 是一个 nameless 对象 - 一个字符串文字。它没有名字,因此任何关于其“范围”的讨论都毫无意义。它没有范围。

您似乎要问的不是范围。它是"Some text!!"生命周期存储期限。 C/C++ 中的字符串文字具有静态存储持续时间,这意味着它们“永远”存在,即只要程序运行。所以,"Some text!!" 占用的内存永远不会被释放。

请记住(作为旁注)字符串文字是不可修改的对象。写入该内存是非法的。

【讨论】:

    【解决方案4】:

    C++ 标准没有说明字符串文字应该存储在哪里。但是,它确实保证它们的生命周期就是程序的生命周期。因此,您的代码是有效的。

    【讨论】:

    猜你喜欢
    • 2012-04-15
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多