C变量的范围[重复]

Posted

技术标签:

【中文标题】C变量的范围[重复]【英文标题】:Scope of C variables [duplicate] 【发布时间】:2012-08-21 18:21:58 【问题描述】:

可能重复:Is returning a string literal address from a function safe and portable?“life-time” of string literal in C

你好,我有点困惑

char *func()
 

    return "Hello";
 

这里的“Hello”是字符序列/数组。它是一个局部变量,一旦函数返回,它就必须消失。那我们怎么能得到正确的值呢?

【问题讨论】:

那不是UB吗?你有没有收到编译器的警告? 不,在这种情况下不是,因为字符串存储在一个常量内存地址中。 但是他返回的是char*而不是const char*不是UB吗? @NeelBasu 是否没有在堆栈上分配字符串文字? @Constantinius 是否没有在堆栈上分配字符串文字? 【参考方案1】:

"Hello" 是一个字符串文字,将在程序的生命周期内存在。引用 C99 标准的相关部分:

6.4.5 字符串字面量

...然后使用多字节字符序列来初始化一个静态存储持续时间数组,长度刚好足以包含该序列...

6.2.4 对象的存储时长

一个对象,其标识符是用外部或内部链接声明的,或者用 存储类说明符 static 具有静态存储持续时间。它的生命周期是整个 程序的执行及其存储的值仅在程序之前初始化一次 启动。

函数的返回值应为const char*,因为尝试修改字符串文字是未定义的行为。

【讨论】:

Strin 字面量是否没有存储在堆栈中?它们是从堆中分配的吗? @GreatCoder 它们被分配在只读内存中,可能称为.rodata 或类似的链接器乱码。 @GreatCoder,它们不存储在堆栈或堆中。它们将直接在生成的二进制文件中编译。我认为将字符串文字编译到的二进制区域称为数据区 @hmjd 通常,链接器将有一个段 .data 和一个段 .rodata,前者用于所有静态存储持续时间变量(未初始化为零,位于 .bss 中)后者用于只读变量,即常量和字符串字面量。 @Lundin,谢谢。我知道这两个部分(已初始化和未初始化),但不知道名称。【参考方案2】:

看看这个:Is returning a string literal address from a function safe and portable?

即使字符串被删除(局部变量或使用 malloc() 和 free() 进行动态分配),当您返回指针时,该值也可能是正确的。但是,这是一种未定义的行为。

【讨论】:

【参考方案3】:

该函数仅在返回控件后才销毁值。因此,在遇到 return 语句时,将“Hello”放置为返回值,然后该函数销毁范围;

【讨论】:

那么它应该在运行时崩溃。问题提到“那我们怎么能得到正确的值” 你错了,因为字符串文字不是本地(自动)变量,也不是在堆栈上分配,而是作为常量、静态只读内存。【参考方案4】:

它是常量并且在内存中有固定的地址。

【讨论】:

怎么样?他从未指定const @NeelBasu 好的,更准确地说是字符串字面量。 字符串文字总是如此。

以上是关于C变量的范围[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Chrome开发工具:监视变量不可用(无法在封闭范围内检测到)[重复]

带有函数的变量范围[重复]

Python嵌套函数变量范围[重复]

Python类变量范围不符合文档[重复]

如何更改函数中变量的范围? Python [重复]

python中变量的范围[重复]