这是 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";

s1s2 地址完全相同

因为编译器会优化:
相同常量只存一份,所有引用指向同一个地址


六、常量区 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。
它不能被修改,相同常量会合并,程序运行全程存在。


更多推荐