不同的数据在内存中会有不同的保存时机,和保存位置,这一节就分析这个。
当运行一个可执行文件时候,操作系统就会把这个可执行文件加载到内存;此时进程有一个虚拟的地址空间(内存空间),如下图:
代码段:装的代码
数据段,BSS段:更准确的说法是:数据段中一块是BSS段。他们两个的地址分配是有一些区别的。
数据段(.data):存储的是全局变量 和静态变量,一般是已经初始化的全局变量
BSS段:存储的是全局变量 和 静态变量 ,但是一般这个全局变量没有初始化,或者是默认给的0,"" ,nullptr
堆:
//中间空间
栈:
搞一段代码验证一下:
// 这里研究 数据段-存储的是全局变量,一般是已经初始化的全局变量
// BBS段 - 存储的是全局变量,但是一般这个全局变量没有初始化,或者是默认给的0,"", nullptr
int *ptest = new int(120);
int g1;
int g2;
int g3 = 12;
int g4 = 32;
int g5;
int g6 = 0;
static int g7;
static int g8 = 0;
static int g9 = 10;
void mygfunc() {
return;
}
class Teacher3 {
public:
int m_i;
static int m_si;//这里是声明一个static,并不是定义,声明不会分配空间
int m_j;
static int m_sj;
int m_k;
static int m_sk;
};
int Teacher3::m_si = 0;//这里才是定义,才会分配空间
void main() {
//打印所有的地址,观察地址空间
printf("ptest 的地址 %p\n", &ptest);
printf("g1 的地址 %p\n", &g1);
printf("g2 的地址 %p\n", &g2);
printf("g5 的地址 %p\n", &g5);
printf("g6 的地址 %p\n", &g6);
printf("g3 的地址 %p\n", &g3);
printf("g4 的地址 %p\n", &g4);
printf("g7 的地址 %p\n", &g7);
printf("g8 的地址 %p\n", &g8);
printf("g9 的地址 %p\n", &g9);
printf("Teacher3 静态成员m_si 的地址 %p\n", &(Teacher3::m_si));
//printf("Teacher3 静态成员m_sj 的地址 %p\n", &(Teacher3::m_sj)); build error
printf("全局方法 mygfunc() 的地址 %p\n", mygfunc);
cout << "用C++的方式打印:全局方法 mygfunc() 的地址" << (void *)mygfunc << endl;
printf("main 方法 的地址 %p\n", main);
// ptest 的地址 00AF4318 //有初始化的全局变量,BSS
// g1 的地址 00AF42E8 //没有初始化的全局变量 BSS
// g2 的地址 00AF42EC // 没有初始化的全局变量 BSS
// g5 的地址 00AF42F0 // 没有初始化的全局变量 BSS
// g6 的地址 00AF42F4 // 初始值为0的全局变量 BSS
// g3 的地址 00AF4000// 有初始值的全局变量 数据段.dada
// g4 的地址 00AF4004 // 有初始值的全局变量 数据段.dada
// g7 的地址 00AF431C // 没有初始值的static BSS
// g8 的地址 00AF4320 //初始值为0的static BSS
// g9 的地址 00AF4008 //初始值为10的static 数据段.dada
// Teacher3 静态成员m_si 的地址 00AF42F8 // 初始值为0的static
// //如下三个都是方法,是在代码段放置的。
// 全局方法 mygfunc() 的地址 00AE169A
// 用C++的方式打印:全局方法 mygfunc() 的地址00AE169A
// main 方法 的地址 00AE1500
}