在函数内返回一个填充了const char*的向量,这是否是良好定义的行为?

7

我目前在学习Vulkan。在其中一个教程中,我看到了一个大致执行以下操作的函数:

#define SOMESTRING "Hello World!"

std::vector<const char*> buildVector() {
    std::vector<const char*> vec;
    vec.push_back(SOMESTRING);
    return vec;
}

当我看到这个时,我在想:这是定义的行为吗?字符串"Hello World!"的内容不会位于栈上并在函数返回后无效吗?如果这是未定义行为,正确的做法是什么?不幸的是,由于Vulkan API的原因,使用std::string不是一个选项。

1
const char * stuff() { return SOMESTRING; }相同。这里的向量没有任何神奇的作用。 - juanchopanza
3
字符串字面值是具有静态存储期的左值。 - Kerrek SB
1个回答

6

是的,因为SOMESTRING的作用域(即该宏所代表的值)属于静态存储区,也就是字符串字面量在整个程序执行期间都存在。而这正是你在此处的情况。


以下是各种情况:

  • #define SOMESTRING "Hello World!"
    --> 没问题。字符串文字存储在静态存储中,因此它们的生命周期从程序开始到结束。

  • const char* SOMESTRING = "Hello World!"
    --> 没问题。与上面相同。

  • char SOMESTRING[] = "Hello World!";
    --> 如果在staticextern范围内声明,则没有问题。
    --> 如果该数组在函数内部作为非静态变量声明,则有问题。

  • char* SOMESTRING = new char[X]; strncpy(SOMESTRING, "Hello World!", N);
    --> 没问题,因为字符串的存储现在在自由存储区(即堆)中,并且将保持这种状态直到被删除。诀窍在于,存储在vector中的字符串必须稍后释放,以防止内存泄漏。

顺便提一下,std::vector 不影响行为的定义或未定义;在这种情况下,它仅取决于如上所示的 C 风格字符串字面值。


1
SOMESTRING 没有“作用域”。它是一个宏,其展开是一个字面量,而不是一个名称。只有名称有作用域。在 C++ 中,“完整生命周期”不是一种生命周期类型。 - Kerrek SB

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