字符串常量在 C++ 中存在多久?

问题描述 投票:0回答:2

我一直想知道,字符串常量在 C++ 中存在多久。例如,如果我在函数内创建一些 const char *str = "something",返回 str 的值是否安全?

我编写了一个示例程序,并且非常惊讶地发现这样的返回值仍然存储了该字符串。这是代码:

#include <iostream>
using namespace std;

const char *func1()
{
    const char *c = "I am a string too";
    return c;
}

void func2(const char *c = "I'm a default string")
{
    cout << c << endl;
}

const int *func3()
{
    const int &b = 10;
    return &b;
}

int main()
{
    const char *c = "I'm a string";
    cout << c << endl;
    cout << func1() << endl;
    func2();
    func2("I'm not a default string");
    cout << *func3() << endl;
    return 0;
}

它给了我以下输出:

我是一根绳子

我也是一根绳子

我是默认字符串

我不是默认字符串

10

func3 的存在只是为了查明是否同样适用于其他类型。
所以问题是:返回指向该函数内创建的字符串常量的指针是否安全(如 func1() 中)?
另外,像 func2() 中那样使用默认字符串值是否安全?

c++ pointers constants string-literals object-lifetime
2个回答
16
投票

字符串文字具有静态存储持续时间并持续程序的生命周期。来自C++标准草案部分

2.14.5
字符串文字段落8其中表示(强调我的前进):

也指普通字符串文字和UTF-8字符串文字 为窄字符串文字。窄字符串文字的类型为“array of n const char”,其中 n 是字符串的大小,定义如下, 并且 具有静态存储持续时间 (3.7)。

以及来自第

3.7.1
静态存储持续时间1段:

所有没有动态存储持续时间的变量,没有 线程存储持续时间,并且不是本地有静态存储 期间。 这些实体的存储应持续到 程序的说明(3.6.2、3.6.3)。

另一方面,

func3
中的第二种情况无效。临时绑定到引用的生命周期在引用的生命周期内持续存在,在本例中,引用在函数返回时结束。这在第
12.2
节中有介绍,其中说:

第二个上下文是当引用绑定到临时对象时。115 引用绑定到的临时对象或作为引用的临时对象 引用绑定到的子对象的完整对象 在引用的生命周期内持续存在,除了:


0
投票
简短回答

我将尝试演示本地(自动)字符串会发生什么

func1中初始化的变量。

  1. 我们看到使用相对寻址(当前地址+硬编码偏移) 我们计算字符串文字地址

  2. 这个地址被放置在寄存器$rax中

  3. 由于

    c是局部变量,它应该定义在堆栈上,我们看到它是使用$rbp中的堆栈地址放入堆栈的

    0x00005555555551f1 <+8>: lea 0xe0c(%rip),%rax #0x555555556004 0x00005555555551f8 <+15>: mov %rax,-0x8(%rbp)
    
    
  4. func1返回时,局部变量c将随func1的栈帧一起被销毁

  5. 局部变量

    c将使用寄存器$rax返回

    0x00005555555551fc <+19>: mov -0x8(%rbp),%rax
    
    
我们在 GDB 的屏幕截图中看到了这一切:

© www.soinside.com 2019 - 2024. All rights reserved.