在C中返回带有const char *的字符串

时间:2013-09-18 06:12:35

标签: c string

我正在尝试理解为什么以下字符串传递适用于我的错误字符串。我从一个更大的来源做了这个例子。

我的问题是;为什么我不必为包含我的错误消息的char数组专门分配内存?我原本以为我需要为字符串malloc一些内存并使用err指针来指示这个内存的开始。

这是否与const char *或{是}因为我正在打印到stderr的事实有关?

我可能写错了问题,这就是为什么搜索没有帮助我理解这一点。

const char * my_function(int a)
{
     if (a != 1)
         return "a doesn't equal 1!"
     else
         return NULL;

}

int main(int a)
{
    const char *err;
    err = my_function(a);
    if (err)
         fprintf(stderr, "Message = %s\n",err);
         return 1;
    return 0;
}

6 个答案:

答案 0 :(得分:7)

所有字符串文字都在编译时分配。程序启动时,它们已驻留在程序存储器的只读部分;它们不是在运行时分配的。您可以将它们视为常量字符数组。和任何const变量一样,它们在整个程序执行过程中仍然有效。

答案 1 :(得分:2)

字符串文字被分配为具有静态存储持续时间的const char数组,因此它们在程序的整个生命周期中都存在。它们碰巧的范围是无关紧要的 - 它们总是具有静态存储持续时间。

这意味着你可以获取它们的地址(如果你返回一个字符串文字或者将它存储在任何地方的const char *变量中,它会隐式发生),而不必担心结果指针的生命周期。字符串文字的存储永远不会用于其他东西。

答案 2 :(得分:2)

你正在返回字符串文字。它保存在静态内存中,但有一个像任何其他字符串一样的地址。所以你可以随时参考那个地址。问题是如果你试图改变字符串文字,我认为这是一种未定义的行为。

答案 3 :(得分:1)

这是因为字符串存储在程序的数据部分中。键入"a doesn't equal 1!"时,内存 已分配,并且该值已写入其中。

你的函数只返回指向那段内存的指针,fprintf很乐意从中读取。

答案 4 :(得分:1)

请注意,main()将始终返回1.

int main(int a)
{
    const char *err;
    err = my_function(a);
    if (err)
         fprintf(stderr, "Message = %s\n",err);
         return 1;
    return 0;
}

return 1缩进,好像它在if (err)之下,但事实并非如此。你真正拥有的是:

int main(int a)
{
    const char *err;
    err = my_function(a);
    if (err)
         fprintf(stderr, "Message = %s\n",err);
    return 1;
    return 0; # Never gets executed.
}

你想要的是:

int main(int a)
{
    const char *err;
    err = my_function(a);
    if (err) {
         fprintf(stderr, "Message = %s\n",err);
         return 1;
    }
    return 0;
}

正是由于这个原因,我总是在我的街区周围使用牙箍,即使它们不是绝对必要的。

答案 5 :(得分:0)

不要太乐观。这是因为子例程中的字符串存储在共享段中(只读),并且可以在例程退出后返回。如果将其定义为char str [] =“your string”,则无法返回该值,因为它在堆栈上“已分配”。堆栈指针将在子例程结束时恢复。