我正在尝试理解为什么以下字符串传递适用于我的错误字符串。我从一个更大的来源做了这个例子。
我的问题是;为什么我不必为包含我的错误消息的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;
}
答案 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”,则无法返回该值,因为它在堆栈上“已分配”。堆栈指针将在子例程结束时恢复。