第五章 常量区和代码区管理
在C语言中,内存分为多个区域,包括栈、堆、全局/静态区、常量区和代码区。常量区和代码区是用于存储程序中不会被修改的数据和代码本身的内存区域。
1. 字符串字面量的存储
字符串字面量(String Literal)通常被存储在常量区(又称文本段或只读数据段)。这些字符串在程序运行期间是只读的,也就是说不能被修改。
示例代码:
#include <stdio.h>
int main() {
// 这两个字符串字面量会被存储在常量区
const char *str1 = "Hello, World!";
const char *str2 = "Hello, World!";
// 比较这两个指针是否相同
if (str1 == str2) {
printf("str1 和 str2 是相同的内存地址。\n");
} else {
printf("str1 和 str2 是不同的内存地址。\n");
}
// 打印字符串
printf("str1: %s\n", str1);
return 0;
}
详细解释:
- 字符串字面量
"Hello, World!"
被存储在常量区。 - 由于编译器的优化,
str1
和str2
指向的是同一个常量区的内存地址。 str1 == str2
判断这两个指针是否指向相同的内存地址,结果通常为真,表示编译器在内存中只分配一个存储该字面量的副本。
需要注意的是,常量区的数据是只读的,试图修改字符串字面量会导致未定义行为。
#include <stdio.h>
int main() {
// 字符串字面量存储在常量区
char *str = "Hello, World!";
// 尝试修改字符串字面量(这是未定义行为,不应该这么做)
str[0] = 'h';
return 0;
}
上述代码在某些编译器和平台上可能会导致程序崩溃,因为你不能修改被存储在常量区的只读数据。
2. 只读数据的存储
只读数据(例如使用 const
修饰的全局变量)也会被存储在常量区。这样做的目的是为了防止程序运行期间这些数据被意外修改。
示例代码:
#include <stdio.h>
// 定义一个全局的只读变量
const int global_const = 42;
void display_const() {
// 打印全局只读变量的值
printf("global_const 的值: %d\n", global_const);
// 尝试修改全局只读变量(这是错误的做法,编译时会报错)
// global_const = 24;
}
int main() {
display_const();
return 0;
}
详细解释:
const int global_const = 42;
定义了一个全局只读变量,将它的值设置为42
。- 尝试在函数
display_const
中修改该变量global_const
会导致编译错误,因为它是只读的。 - 这种全局的只读变量一般也会被存储在常量区或者其他只读数据段中。
通常情况下,为了内存区域的保护管理,编译器和运行时系统会确保常量区的数据是不可修改的。这样的分隔和区分有助于提高程序的安全性和稳定性。
总结
常量区(或称文本段、只读数据段)是程序存储字符串字面量和只读数据(如用 const
修饰的全局变量)的地方。这些数据在程序运行期间是不可修改的,通过这样的设计可以帮助程序避免意外修改的重要数据,提高程序的稳定性和安全性。