从C函数返回字符串

时间:2016-07-01 13:33:28

标签: c memory-management stack

我有一个简单的代码。

#define MY_STRING "String example"

char* string_return_function()
{
    return MY_STRING;
}

以上代码有效,但我不知道如何。我认为string_return_function()返回一个本地地址,一旦该函数退出就会被释放。

3 个答案:

答案 0 :(得分:6)

不,这不是它的工作方式。

字符串文字存储在内存中,只要程序运行就会持续存在,因此该函数只返回指向字符串常量的指针。

在运行时没有发生字符串创建/初始化,没有复制任何字符。它只是返回一个指针,函数的机器代码可能只是几个指令。

例如,这是我从https://assembly.ynh.io/获得的(清理过的)x86代码:

string_return_function:
  movl  $.LC0, %eax
  ret

.LC0只是一个持有字符串的位置。那么,这是2条指令,包括从功能开销/样板回归。很有效率。 :)

你在想这个:

char * bad_code(void)
{
  char response[] = MY_STRING;
  return response;
}

这是错误代码,因为它返回一个本地数组。有问题的数组是从文字中初始化的,这不是什么原因。

另外,不要以str开头命名您的函数,所有这些名称都是保留的; C11草案说:

  

strmemwcs开头且小写的函数名称   可以在<string.h>标题中的声明中添加字母。

答案 1 :(得分:2)

字符串文字在静态只读内存中分配,通常称为.rodata(只读数据)。它们在程序的整个生命周期中都会持续存在,因此可以安全地将指针返回给它。

但是,如果您将字符串文字复制到临时堆栈变量中,则代码将不安全并调用未定义的行为:

char* string_return_function()
{
    char mystring [] = "String example";
    return mystring; // BAD
}

答案 2 :(得分:1)

字符串文字导致数组char具有静态存储持续时间。

例如,1999 C标准第6.4.5节第5段以

开头
  

在转换阶段7中,将值0的字节或代码附加到由字符串文字或文字产生的每个多字节字符序列.65)然后使用多字节字符序列初始化静态存储持续时间和长度的数组足以包含序列。

静态存储持续时间意味着在函数string_return_function()返回后,表示字符串文字的数组仍然存在。