从C函数返回字符串
我有一个简单的代码。
#define MY_STRING "String example" char* string_return_function() { return MY_STRING; }
上面的代码有效,但我不知道如何。 我认为string_return_function()返回一个本地地址,一旦该函数退出就会被释放。
不,这不是它的工作原理。
字符串文字存储在内存中,只要程序运行就会持续存在,因此该函数只返回指向字符串常量的指针。
在运行时没有发生字符串创建/初始化,没有复制任何字符。 它只是返回一个指针,该函数的机器代码可能只是几个指令。
例如,这是我从https://assembly.ynh.io/获得的(清理过的)x86代码:
string_return_function: movl $.LC0, %eax ret
其中.LC0
只是一个持有字符串的位置。 所以,这是2条指令,包括从function开销/样板文件返回。 很有效率。 🙂
你在想这个:
char * bad_code(void) { char response[] = MY_STRING; return response; }
这是错误的代码,因为它返回一个本地数组。 有问题的数组是从文字初始化的,这不是什么被返回。
另外,不要以str
开头命名函数,保留所有这些名称; C11草案说:
以
str
,mem
或wcs
开头的函数名和小写字母可以添加到头中的声明中。
字符串文字在静态只读内存中分配,通常称为.rodata
(只读数据)。 它们在程序的整个生命周期中都会持续存在,因此返回一个指针是安全的。
但是,如果您将字符串文字复制到临时堆栈变量中,则代码将是不安全的并调用未定义的行为:
char* string_return_function() { char mystring [] = "String example"; return mystring; // BAD }
字符串文字导致具有静态存储持续时间的char
数组。
例如,1999 C标准,第6.4.5节,第5段开头
在转换阶段7中,将值0的字节或代码附加到由字符串文字或文字产生的每个多字节字符序列.65)然后使用多字节字符序列初始化静态存储持续时间和长度的数组,该数组足以满足包含序列。
静态存储持续时间意味着在函数string_return_function()
返回后,表示字符串文字的数组继续存在。