返回本地创建的const char*

7
#include <iostream>


const char* fun()
{
    const char* x = "abc";
    std::cout << "x = " << x << "\n";
    return x;
}


int main(int arc, char** argv)
{
    const char* y = fun();
    std::cout << "y = " << y << "\n";
    return 0;
}

在我的电脑上运行这个程序会得到以下结果:
x = abc

y = abc

在`fun()`函数中,`x`(一个局部变量)被赋予一个本地创建的字符串字面量的地址,然而当函数返回时,指向`y`的数据与指向`x`的数据相同,尽管`x`已经超出了其作用域。
有人能详细解释一下这里发生了什么吗?

你忽略的一点是函数始终可以返回其自身类型的值。 指针的注意事项是它们所指向的内容必须在函数返回后仍然存在。如下@songuyanyao所解释。 - David C. Rankin
2个回答

7
这是格式良好的,返回的指针有效且未悬空;因为字符串字面量(即"abc")具有静态存储期,并在程序的整个生命周期中存在。

字符串字面量具有静态存储期,因此在程序的生命周期内存在于内存中。

正如你所说,当函数返回时,局部变量x被销毁,但它所指向的字符串字面量并没有被销毁。

1
关于您的函数 fun
const char* fun(){
    const char* x = "abc";
    std::cout << "x = " << x << "\n";
    return x;
}// the pointer returns but it's content still alive, because it points to string literal

如果你将函数fun更改为以下内容:
const char* fun(){
    char x[] = "abc";
    std::cout << "x = " << x << "\n";
    return x;
}// the pointer returns but it's content died

然后:
const char* y = fun();
std::cout << "y = " << y << "\n"; 

输出结果符合预期(y为空):

enter image description here

因为上面的const char* x = "abc";不是局部变量,它是字符串字面量,具有静态存储期,在整个程序生命周期中存在。
相反,char x[] = "abc";是局部变量,当超出作用域时会被销毁。

你只对了一半。无论是 char x[] 还是 char *x,都不重要,重要的是 "abc";"abc" 是在 .rodata(只读)数据段中创建的字符串字面量。无论你如何声明 xreturn x 都会返回一个指针,其中包含字面量中第一个字符的地址。 - David C. Rankin
我只是举个例子,为了更好地理解。 - Jayhello
好的,语句“相反,char x[] =“abc”;是局部变量,当超出范围时将会死亡。”不太清楚。(你使用的“相反”似乎是试图使用“不相关”,请参见Merriam-Wester - David C. Rankin
对于一个行为未定义的程序来说,不存在“如预期”的情况。任何事情都可能发生,包括与正确程序完全相同的工作方式。我会说一些类似于“毫不奇怪,这个程序表现出了不同的行为:”的话。 - aschepler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接