6

I'm trying to understand why the following string passing works for my error string. I have made this example from a much bigger source I have.

My question is; why don't I have to specifically allocate memory for the char array which contains my error message? I would have thought that I need to malloc some memory for the string and use the err pointer to indicate the start of this memory.

Is this to do with that fact that its a const char * or is is because I'm printing to stderr?

I'm possibly wording the question wrong which is why searches haven't helped me to understand this.

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;
}
4

6 回答 6

10

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

于 2013-09-18T06:24:07.173 回答
3

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

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

于 2013-09-18T06:17:31.073 回答
2

您正在返回字符串文字。它保存在静态内存中,但具有与任何其他字符串一样的地址。因此,您可以随时参考该地址。问题是如果您尝试更改字符串文字,我认为这是一种未定义的行为。

于 2013-09-18T06:18:02.810 回答
2

请注意,您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;
}

正是由于这个原因,我总是在我的块周围使用大括号,即使它们不是绝对必要的。

于 2013-09-18T18:48:51.453 回答
1

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

您的函数仅返回指向该内存片的指针,并fprintf乐于从中读取。

于 2013-09-18T06:17:44.123 回答
0

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

于 2013-09-18T06:50:10.277 回答