Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回C中带有常量char*的字符串_C_String - Fatal编程技术网

返回C中带有常量char*的字符串

返回C中带有常量char*的字符串,c,string,C,String,我试图理解为什么下面的字符串传递对我的错误字符串有效。我已经从一个更大的来源做了这个例子 我的问题是,;为什么我不需要为包含错误消息的char数组专门分配内存呢?我本以为我需要为字符串malloc一些内存,并使用err指针指示该内存的开始 这是因为它是一个常量字符*,还是因为我正在打印到stderr 我可能把这个问题写错了,这就是为什么搜索没有帮助我理解这个问题 const char * my_function(int a) { if (a != 1) return

我试图理解为什么下面的字符串传递对我的错误字符串有效。我已经从一个更大的来源做了这个例子

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

这是因为它是一个
常量字符*
,还是因为我正在打印到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;
}

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


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

这是因为字符串存储在程序的数据部分。当您键入
“a不等于1!”
时,内存将被分配,该值将写入内存中


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

返回的是字符串文字。它被保存在静态内存中,但有一个和其他字符串一样的地址。所以你可以随时查阅那个地址。问题是,如果您试图更改字符串文字,我认为这是一种未定义的行为。

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

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

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

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

请参阅:分配了多少内存?刚好够我返回的字符串吗?如果我有另一个函数将常量char*返回到同一地址怎么办?但是更长了吗?刚好够你的字符串使用,请查看生成的程序集以了解它是如何工作的。我不明白你的第二个问题,“但是更长了”是什么意思?另一个返回相同指针的函数可以正常工作。您可以在
printf
函数中使用
%p
查看指针指向的实际地址。@Markus字符串文字在程序编译时被“分配”(运行时,操作系统将代码和数据复制到内存中,基本上为它们分配实际内存)。它们存储在二进制文件中。您可以在Unix上使用
strings
之类的工具查看它们。“所有字符串文本都是在编译时分配的。”-对我来说,这是所有答案中最有用的部分。“所有字符串文本都是在编译时分配的。”这句话真的正确吗?我相信编译时不会分配任何内容。如果它是在编译时分配的,那么它什么时候被释放呢?@Kolyunya Link time,如果你很挑剔的话。字符串文本通常放在名为
.rodata
的内存段中。这是因为子程序中的字符串存储在共享段(只读)中,可以在例程退出后返回。如果将其定义为char str[]=“your string”,则无法返回该值,因为它在堆栈上是“已分配”的。堆栈指针将在子程序结束时恢复。所以@Ludin的答案在这里只是局部的。