You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言:char指针指向新地址时旧静态字符串的内存状态及示例4解析

关于静态字符串"Hello"在示例4中的内存状态详解

咱们先把基础知识点摆明白:C语言里的静态字符串(比如"Hello"这种直接写的字符串字面量),编译时会被放到程序的只读数据段(通常是.rodata段)里,它的生命周期是从程序加载启动,一直到程序退出为止——本质上是操作系统在程序启动时把这块内存映射到进程空间,退出时再回收。

回到你问的示例4代码:

char* foo = "Hello"; 
printf("%s\n", foo);
char* bar = "World";
foo = bar; 

开启编译器优化后,这里的"Hello"内存状态可以拆解成这几点来说:

  • 内存位置完全不动,不会被清理
    因为printf("%s\n", foo)这行代码实打实用到了"Hello"——程序运行到这里时必须能读取到这个字符串的内容,所以编译器在优化阶段根本没法判定这个字符串是"无用的"。它会老老实实地把"Hello"放进二进制文件的只读数据段,程序加载后这块内存就一直存在,直到整个程序退出才会被操作系统回收。哪怕之后foo改成指向"World","Hello"所在的内存也不会被修改、释放或者移动。

  • 没有运行时回收逻辑
    C语言本身没有自动垃圾回收机制,对于静态存储的字符串,编译器也不会生成任何在运行时释放它的代码。静态存储的对象规则就是"一旦加载,全程存在",跟有没有指针指向它没关系——就算没有任何指针再指向"Hello",它也会安安稳稳待在只读数据段里,直到程序结束。

  • 优化不会影响它的存在
    对比示例2的情况:示例2里"Hello"从始至终没被使用过,开启优化后编译器会直接把它从二进制里删掉,根本不会加载到内存。但示例4里因为有printf的使用,编译器必须保留这个字符串,优化开关在这里只会影响一些其他无关的代码(比如可能把变量的存储优化到寄存器之类的),但动不了"Hello"的存在。

简单总结:示例4里执行foo = bar;之后,"Hello"还是待在原来的只读内存位置,完全没变化,只是现在没有指针指向它了而已——就像你把抽屉的钥匙丢了,但抽屉本身还在柜子里,直到你把柜子(程序)搬走才会消失。

内容的提问来源于stack exchange,提问作者ShellX3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:24:06