返回指向局部变量的指针是否总是未定义行为?

3
我读到过不应该返回指向局部变量的指针或引用。因此在下面给出的例子中,我明白当我在函数foo中写入return f;时,我正在返回一个指向局部变量的指针。在函数外使用该指针将导致未定义行为。
#include <iostream>

const char* foo()
{
    const char* f = "ffdf";
    return f;//returning pointer to a local variable
}

const char* func()
{
    return "fsfs";
}

int main()
{
    const char* ptr = func();
    const char* f = foo();
    std::cout<<f<<std::endl; //I know this is undefined behavior because we're using a pointer that points to a local variable 
    std::cout<<ptr; //But IS THIS UNDEFINED BEHAVIOR too?
}

我的问题是,对于函数func中的返回语句return "fsfs";是否也适用于同样的情况。我知道在C++17中有强制复制优化。因此我的问题针对所有现代C++版本(C++11、C++17等)。行为是否依赖/在不同的C++版本中有所不同。
特别地,我知道main函数内的语句std::cout<<f<<std::endl;总是未定义行为,因为我们正在使用指向局部变量的指针(悬挂指针)。但是语句std::cout<<ptr;是否也会导致未定义行为。如果不会,那么为什么?这里会发生什么。
PS:我可能在描述第一个cout语句时描述错误了。如果我错了,请纠正我。此外,我的原意并不限于特定类型,比如字符串字面量。例如,我可以选择返回一个int而不是字符串字面量,并将返回类型设置为const int&。但既然已经有人开始回答了,我就不改变例子来使用int了。

据我所知,字符串字面量没有生命周期。 - apple apple
哦,而且foo也不是UB(请重新阅读你的问题)。 - apple apple
可能是这个的重复问题。 - no more sigsegv
5
你并没有返回一个指向本地变量的指针。你返回的是一个本地变量的值,这并不会出现问题。如果你写成了return &f;,那就是返回一个指向本地变量的指针了。 - Raymond Chen
@RaymondChen 是的,我刚刚意识到了。 - Jason
显示剩余3条评论
1个回答

6

返回指向非静态函数局部变量的指针将导致你在调用点得到的指针成为悬空指针,并使用它将具有未定义行为。

在这里,这种情况并不适用。字符串字面值具有静态存储期限,意味着它将继续存在直到程序结束。这意味着安全地返回在函数中声明的字符串字面值指针。

因此,foofunc都是安全的,但如果你有以下代码:

const char * bar()
{
    std::string text = "some text";
    // stuff
    return text.c_str();
}

那么你会返回一个指向不存在的对象的指针,尝试从该返回指针读取将导致未定义行为。


那么你如何解决你的例子中的bar? - kingsjester
char *cstr = new char[str.length() + 1]; strcpy(cstr, str.c_str()); return cstr; - kingsjester
@kingsjester,你可以像OP在foofunc中所做的那样,或者将函数改为返回一个std::string - NathanOliver

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