为什么返回带有字符串文字的const char *的函数有效?

时间:2019-05-17 03:21:33

标签: c malloc libcurl

我在libcurl中发现了code,如下所示:

const char *
curl_easy_strerror(CURLcode error)
{
  switch(error) {
  case CURLE_OK:
    return "No error";

  case CURLE_UNSUPPORTED_PROTOCOL:
    return "Unsupported protocol";
.....
}

据我所知,如果要返回指针,则需要确保指针所指向的内存不会被更改或释放。为什么此libcurl代码有效?

2 个答案:

答案 0 :(得分:10)

这些字符串文字在编译时放在可执行文件的静态只读部分中。它们与堆或堆栈分开。该函数只是返回一个指向这些字符串的指针。

参考

此实现是特定于平台和编译器的,但是C11标准在6.4.5节中对此有一些相关要求。

  

在翻译阶段7中,每个多字节附加一个字节或零值的代码   由一个或多个字符串文字产生的字符序列。多字节字符   然后使用序列来初始化静态存储持续时间和长度的数组   足以包含序列。

因此我们知道它必须在编译时存储在静态位置。

  

如果程序尝试修改这样的数组,则行为是   未定义。

这告诉我们数据必须是只读的。

编辑

有人引用特定的平台或体系结构,抱怨这是不正确的。如上所述,这是特定于平台和编译器的

某些平台可能不支持只读数据,但是编译器几乎肯定会尝试阻止您对其进行修改。由于行为是不确定的,因此您永远都不会这样做,因此对于所有意图和目的而言,数据都是只读的。

在问题中,这个答案是正确的。

答案 1 :(得分:4)

根据C标准(6.4.5 字符串文字,第6段),字符串文字具有静态的存储期限:

  

一个或多个字符串文字产生的每个多字节字符序列后面附加一个零值的字节或代码。然后,将多字节字符序列用于初始化静态存储持续时间数组[…]

这意味着无论其物理内存在哪里,都可以保证它们不会超出函数返回的寿命,并且指向该内存的指针仍然有效。

因此,您将返回一个指向保证有效的内存位置的指针,该指针包含字符串文字给出的值。