由于内存分区 ,网上各有**叫法混乱,**在这里把易混点做了区分。
程序中变量的作用域 和生命周期,也做了梳理。
并对**"数组字符串"** 和"指针指向字符串 ",在局部变量返回地址时,为什么有的能返回地址,有的不能返回地址
内存细化

作用域和生命周期


为什么不能返回局部变量的地址
要认知到一点:**字符串字面量本体(也就是 "beoko" 这个双引号包裹的常量):永远存在 .rodata 只读常量区,生命周期为程序全程,**和它写在函数内部还是外部没有任何关系。
char str\[\] 数组:完整存储在栈上,属于局部自动变量;它只是把常量区的字符串内容拷贝了一份副本到栈里,数组本身的位置由它的存储类型决定,和字面量的位置无关。
举例:
1、指针指向字符串地址
cpp
char *p = "beoko"
指针 p 本身在栈上(4/8 字节),指针只存地址,不持有字符串内容
指针直接指向 .rodata 里的字面量本体 ,不可通过指针更改.rodata常量,会触发段错误
2、数组复制一份字符串的副本到栈上
cpp
char str[] = "beoko"
整个数组(6 字节)都在栈上
数组内容是字面量的栈上副本,可修改数组内容
什么情况下返回字符串地址是安全的?
R
char *good_func(void) {
char *s = "beoko";
// s 本身是栈上的指针变量,但它存的值是常量区字符串的首地址
return s;
// 返回的是「常量区的地址值」,不是栈上数据的地址
}
- 栈上消失的只是
s这个指针变量本身(一个存地址的 4/8 字节小变量); - 但它保存的地址值,指向的是
.rodata常量区;常量区是静态存储期,程序全程有效,内容也不会被任何函数覆盖。
一句话区分两种易混淆写法
char str[] = "beoko":返回数组名 → 返回栈地址 → 危险char *str = "beoko":返回指针值 → 返回常量区地址 → 安全