BSS是英文Block Started by Symbol的简称,BSS段属于静态内存分配(包括静态变量和全局变量)。全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。
uninitialized data和initialized data统称为全局数据区
栈区往地址减小方向增长,堆区往地址增大方向增长。
text区又叫代码区(或代码段),这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
char *s = "HelloWorld";
指针s存放于栈区,"HelloWorld"存放于text区,不可修改 *s = ‘h’ 尝试修改字符串第一个字符,将会出现编译通过,运行报错的情况,因为text区一般是只读的,不可修改。
字符串常量和const修饰的变量的区别: char a = ‘A’; // a存放在栈区 const char b = ‘B’; //b还是存放在栈区,const修饰的变量仅仅是告诉编译器b是一个常量,后续程序中若出现尝试修改b的操作时将会在编译时就报错。
举例分析:
#include <iostream>
int global_a = 1;
static int global_b = 2;
int global_c = 3;
int global_d;
int global_e;
int main()
{
int a = 11;
int b = 22;
int c = 33;
static int static_a = 4;
static int static_b;
static int static_c;
printf("a的地址为:%p\n", &a);
printf("b的地址为:%p\n", &b);
printf("c的地址为:%p\n", &c);
int arr[5] = { 1,2,3,4,5 };
int len = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < len; i++)
{
printf("&arr[%d]: %p\n", i, &arr[i]);
}
printf("global_a的地址为:%p\n", &global_a);
printf("global_b的地址为:%p\n", &global_b);
printf("global_c的地址为:%p\n", &global_c);
printf("global_d的地址为:%p\n", &global_d);
printf("global_e的地址为:%p\n", &global_e);
printf("static_a的地址为:%p\n", &static_a);
printf("static_b的地址为:%p\n", &static_b);
printf("static_c的地址为:%p\n", &static_c);
char s1[] = "HelloWorld";
char* s2 = "HelloWorld";
char* s3 = "HelloWorld";
printf("s1:%p\n", s1);
printf("s2:%p\n", s2);
printf("s3:%p\n", s3);
}
结果: 内存划分:
结果分析:
-
因为栈是由地址高的向地址低的方向开辟空间,因此a、b、c三个变量的地址是依次减小的。而数组arr是先整体开辟空间,数组内部元素在数组整体所开辟的空间内自下而上(低地址->高地址)划分空间。 -
char s1[] = “HelloWorld”; 这里是在栈上为s1申请了一段空间,其中的值赋成的"HelloWorld" char* s2 = “HelloWorld”;这里的"HelloWorld"存储在代码段,具体来说是代码段中的常量区
参考: 1.【C语言】内存分区 2.C语言内存分配
|