C++ 常量区(只读数据段 .rodata)
·
这是 C++ 内存模型里最容易踩坑、面试最爱问的区域,我给你讲得透彻、底层、无废话。
一、常量区到底是什么?
常量区(Read-only Data Segment,简称 .rodata)
是程序运行时的一块只读内存区域,专门存放不会被修改的常量数据。
它属于进程虚拟地址空间的一部分,特点:
- 只读!不能写! 一旦修改直接崩溃(段错误)
- 程序运行期间一直存在
- 多个相同常量会合并(节省空间)
- 属于数据段的一部分,和代码区分开
二、哪些东西会放进常量区?
1. 字符串常量(最典型)
"hello world";
"abc";
"123";
这些都直接存在 常量区。
2. const 修饰的全局变量 / 静态变量
const int a = 10; // 全局 const → 常量区
static const int b=20; // 静态 const → 常量区
3. 其他编译期就能确定的常量
例如:
const char* str = "test";
"test" 本身 → 常量区str 是指针变量 → 栈区
三、最重要特性:只读!不能修改!
这是常量区最核心、最容易出错的地方。
例子 1:修改字符串常量 → 崩溃!
char* p = (char*)"hello";
p[0] = 'A'; // ❌ 程序直接崩溃!
原因:"hello" 存在 常量区(只读),强行写操作 = 非法访问。
例子 2:正确写法
const char* p = "hello";
p[0] = 'A'; // ❌ 编译直接报错,保护你
四、const 变量 到底放哪里?(面试高频)
这里 90% 的人都会混淆!
1. 全局 const / 静态 const
const int a = 10;
static const int b = 20;
→ 常量区(只读)
2. 局部 const
void func(){
const int c = 10;
}
→ 栈区,只是受语法限制不能改,不是真正的只读内存
3. const 字符串
const char* s = "abc";
s(指针)→ 栈区"abc" → 常量区
五、常量区的「常量合并」机制
相同字符串只会存一份!
const char* s1 = "hello";
const char* s2 = "hello";
s1 和 s2 地址完全相同!
因为编译器会优化:
相同常量只存一份,所有引用指向同一个地址
六、常量区 vs 栈区 vs 堆区
| 区域 | 存储内容 | 权限 | 生命周期 |
|---|---|---|---|
| 常量区 | 字符串、全局const、静态const | 只读 | 全程 |
| 栈区 | 局部变量、形参 | 读写 | 函数内 |
| 堆区 | new/malloc | 读写 | 手动管理 |
七、底层原理(进阶)
- 常量区在 .rodata 段
- 操作系统会给这块内存 设为只读保护
- 任何写入指令都会触发 硬件级保护错误 → 程序崩溃
- 属于进程空间,不与其他进程共享(除了代码段)
八、最经典面试题(必看)
题目 1
char str1[] = "hello";
char str2[] = "hello";
const char* str3 = "hello";
const char* str4 = "hello";
问:
str1 == str2?
→ 不等(数组在栈区,各存一份)str3 == str4?
→ 相等(都指向常量区同一份数据)
九、一句话终极总结
常量区就是一块只读内存,专门存字符串常量、全局const、静态const。
它不能被修改,相同常量会合并,程序运行全程存在。
更多推荐
所有评论(0)