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