【发布时间】:2019-06-19 12:35:15
【问题描述】:
我一直在阅读各种来源,字符串文字在程序的整个生命周期内都保留在内存中。那么,这两个函数有什么区别
char *f1() { return "hello"; }
char *f2() {
char str[] = "hello";
return str;
}
虽然f1 编译良好,但f2 抱怨我正在返回堆栈分配的数据。这里发生了什么?
- 如果
str指向实际 字符串文字(具有静态持续时间),为什么会出现错误? - 如果将字符串文字复制到局部变量
str,那么原始字符串文字会去哪里?它是否保留在内存中而不引用它?
【问题讨论】:
-
在
char str[] = "hello"中,"hello"保持静态,str包含堆栈上字符串的副本。然后,您返回一个指向堆栈上该副本的指针。 -
(为了过于迂腐,一个字符串字面量就是源代码中引用的字符串。当程序被翻译[编译]时,字符串字面量用于初始化一个静态存储时长的数组。那数组是另一回事;它不是字符串文字,但人们通常将其称为字符串文字。)
-
@EricPostpischil:拜托,学究一点!!
char str[] = "hello"是否将这个静态数组逐个元素地复制到自动数组中?静态的还存在吗?如果是这样,你能指出一个参考,我在规范中找不到它.. -
@blue_note:C 标准将 C 定义为抽象机器,即经过基本步骤的假想计算机。在那个抽象机器中,是的,
char str[] = "hello"中的"hello"导致创建一个包含 h、e、l、l、o 和空字符的静态存储持续时间数组,并且该数组用于初始化 @987654332 @。编译器不必实现实际的抽象机;他们可以创建任何获得相同结果的程序(与 C 标准定义的相同观察到的行为)。所以他们会优化。 -
@blue_note:再举一个例子,如果
char str[] = "a"出现在函数中,则字符串足够短以至于编译器可能不会将空字符作为静态对象存储在对象模块中。相反,它可能将其实现为指令流中的立即操作数。抽象机有一个字符串字面量,但编译器生成的优化代码不需要。
标签: c arrays initialization implicit-conversion string-literals