此问题已在此处有答案:
Returning a pointer to a literal (or constant) character array (string)(3个答案)
10年前关闭。
我试图理解为什么下面的字符串传递对我的错误字符串有效。我从一个更大的来源做了这个例子。
为什么我不必为包含错误消息的char数组专门分配内存?我会认为我需要malloc一些内存来存储字符串,并使用err
指针来指示这个内存的开始。
这是因为它是一个const char *
,还是因为我打印到标准错误?
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条答案
按热度按时间8cdiaqws1#
所有字符串文字都是在编译时分配的。当你的程序启动时,它们已经驻留在程序内存的只读部分;它们不是在运行时分配的。您可以将它们视为常量字符数组。像任何
const
变量一样,它们在整个程序执行过程中保持有效。luaexgnf2#
字符串字面量被分配为具有静态存储持续时间的const char数组,因此它们在程序的整个生命周期中都存在。它们所处的作用域是无关紧要的--它们总是具有静态存储持续时间。
这意味着你可以获取它们的地址(如果你返回一个字符串字面量或将其存储在任何地方的const char * 变量中,就会隐式地发生),而不必担心结果指针的生命周期。字符串字面量的存储永远不会用于其他事情。
p1tboqfb3#
请注意,您的
main()
将始终返回1。return 1
是缩进的,就好像它在if (err)
下面一样,但事实并非如此。你真正拥有的是:你想要的是:
正是由于这个原因,我总是在我的块周围使用大括号,即使它们不是严格必要的。
xam8gpfp4#
返回的是字符串文字。它被保存在静态内存中,但像其他字符串一样有一个地址。所以你可以随时查阅那个地址。一个问题是如果你试图改变字符串字面量,我相信是undefined behaviour。
eivnm1vs5#
这是因为字符串存储在程序的数据部分。当您键入
"a doesn't equal 1!"
时,内存被分配,并且该值被写入其中。你的函数仅仅返回指向该内存片的指针,
fprintf
很乐意从中读取。eqoofvh96#
不要太乐观。这是因为子例程中的字符串存储在共享段中(只读),并且可以在例程退出后返回。如果你将其定义为char str[]=“your string”,你将无法返回该值,因为它在堆栈上被“分配”。堆栈指针将在子程序结束时恢复。