返回C中带有const char * 的字符串[duplicate]

41ik7eoe  于 2023-10-16  发布在  其他
关注(0)|答案(6)|浏览(88)

此问题已在此处有答案

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;
}
8cdiaqws

8cdiaqws1#

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

luaexgnf

luaexgnf2#

字符串字面量被分配为具有静态存储持续时间的const char数组,因此它们在程序的整个生命周期中都存在。它们所处的作用域是无关紧要的--它们总是具有静态存储持续时间。
这意味着你可以获取它们的地址(如果你返回一个字符串字面量或将其存储在任何地方的const char * 变量中,就会隐式地发生),而不必担心结果指针的生命周期。字符串字面量的存储永远不会用于其他事情。

p1tboqfb

p1tboqfb3#

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

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

xam8gpfp

xam8gpfp4#

返回的是字符串文字。它被保存在静态内存中,但像其他字符串一样有一个地址。所以你可以随时查阅那个地址。一个问题是如果你试图改变字符串字面量,我相信是undefined behaviour

eivnm1vs

eivnm1vs5#

这是因为字符串存储在程序的数据部分。当您键入"a doesn't equal 1!"时,内存分配,并且该值被写入其中。
你的函数仅仅返回指向该内存片的指针,fprintf很乐意从中读取。

eqoofvh9

eqoofvh96#

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

相关问题