通过从本地C风格的数组返回指针来获取悬空指针

vso*_*tco 48 c++ memory pointers undefined-behavior

我对以下代码感到有点困惑:

#include <iostream>

const char* f()
{
    const char* arr[]={"test"};
    return arr[0];
}

int main()
{
    auto x = f();
    std::cout << x;
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这段代码应该是UB(未定义的行为).我们返回一个指向本地范围内的C风格数组元素的指针.事情应该出问题.但是,我测试过的编译器都没有抱怨(我用过-Wall -Wextra -pedanticg ++和clang).valgrind也不抱怨.

上面的代码是有效的还是人们会想到的UB?

PS:运行它似乎产生"正确"的结果,即显示"测试",但这并不表示正确性.

Bar*_*rry 77

不,这不是UB.

这个:

const char* f()
{
    const char* arr[]={"test"};
    return arr[0];
}
Run Code Online (Sandbox Code Playgroud)

可以改写为等效的:

const char* f()
{
    const char* arr0 = "test";
    return arr0;
}
Run Code Online (Sandbox Code Playgroud)

所以我们只是将一个本地指针返回给字符串文字.字符串文字具有静态存储持续时间,没有任何悬挂.功能真的如下:

const char* f()
{
    return "test";
}
Run Code Online (Sandbox Code Playgroud)

如果你做了这样的事情:

const char* f() {
    const char arr[] = "test"; // local array of char, not array of char const*
    return arr;
}
Run Code Online (Sandbox Code Playgroud)

现在是UB - 我们正在返回一个悬空指针.

  • @LightnessRacesinOrbit,在这两种情况下,都有一个指向`const char`的本地指针,在这两种情况下,本地指针都被初始化为指向文字字符串,在这两种情况下都返回它的值.唯一的区别是,在原始示例中,本地指针是一个元素数组的成员,而在备用版本中,它是一个标量.那么,如果有一些感觉,那些不是"等同"的呢?这里重要的不是局部变量的确切类型.重要的是在函数返回后字符串文字是否仍然有效. (4认同)
  • 不要迂腐,但这并不是"等同".从功能上讲,在这种情况下,确定,但数组是一个数组是一个数组.;) (3认同)
  • C还保证字符串文字具有静态存储持续时间,请参阅http://port70.net/~nsz/c/c11/n1570.html#6.4.5p6. (2认同)