#include <iostream>
#include <string.h>
using namespace std;
// 程序的内存地址的划分
// 1. 操作系统位数不同,地址划分也会存在一定的差别。但是有一些核心区域是固定的
// 内存区域划分:
// 保留区:0开始,C库函数(不能变动)
// 代码区: 一个程序执行的时候,会按照次序依次从代码区调用程序运行(也是不可修改的)
// 全局变量区: 包括两个部分:.data (非0值)、.bss(未初始化的值)
// 静态局部变量
// 静态全局变量
// 堆区和栈区是可以进行修改的
// 堆区(地址从低到高):
// new 分配: 每次申请的时候,会从已释放的内存快中申请可用的,也有可能按照次序往下去执行(做内存池的时候,需要考虑的内容)
// delete 释放:不会将快内存空间进行擦除,而是将分配的空间标注为已释放。
// 堆区的内存空间分配之后,若没有主动删除,不会一直占用。因为进程一旦退出,那么所占用的内存就会变得毫无意义
// 指针指向的地址并不是实际物理内存的空间地址,而是一个虚拟地址。当进程退出的时候,将指针和内存地址之间的联系之间砍掉,那这一部分的内存空间其他进行就可以使用了
// 栈区(地址从高到低):内存从高往低进行分配
// (当栈区和堆区内存汇合的时候,程序内存使用完全,没有多余内存可以分配。 但是在一些新的操作系统上,可能会将这一机制进行改善,利用分块技术来避免这一现象产生)
// 是{} 内定义的变量,出了 {} 程序会自动进行清理
// 命令行参数环境变量:程序运行的时候,会加载一部分命令行参数,因此,在程序运行的过程中,修改环境变量是不能产生作用的
// 内核空间:程序运行的时候,会将一部分内存空间分配给内核空间,调度进程的操作系统部分来操作硬件(window下一般是2G,Linux 1G)
// 整个代码以初始化分配的内存空间为准。后面更改则不会更改内存地址
int g1; // .bss 未被初始化
int g2 = 0;
// 在一块内存
int g3 = 20; // .data(非0值) 初始化
int g4 = 40; // .data (非0值)初始化
static int g6;
static int g7 = 200;
void test01(){
// s
int arr1[10]; // 变量内部存放的值是不确定的,因为变量是存放在栈空间的,而出栈和入栈的操作,不会将内存释放掉。因此在重新入栈变量的时候,不确定是上次赋值的哪一块儿区域,值页不确定
memset(arr1, 0, sizeof(arr1)); // 置为0
// int arr1[10] = {0}; // 全部设置为0
char str1[] = "tets01"; // 将 “test01” 的内存空间赋值到 str1(多一个字节\0)
// 在栈空间中,数组的分配大小不能使用动态产生
// 在堆空间中,数组的大小分配是可以动态产生,(也就是可以使用变量来指定变量个数)
// 当一个指针指向的是堆内存空间大小的时候,使用 sizeof 获取的是指针的大小
// 当一个指针指向的是栈内存空间大小的时候,使用 sizeof 获取的是指向的数据内存大小
}
int main(int argc, char ** argv){
static int mg1 = 20;
cout << "代码区: main() 的地址: " << main << endl; // 输出为 1 ?
// test01();
cout << "&g1 = " << &g1 << endl;
cout << "g2 = 0==> &g2 = " << &g2 << endl;
cout << "g3 = 20 ==> &g3 = " << &g3 << endl;
cout << "g4 = 40 ==> &g4 = " << &g4 << endl;
// 代码区: main() 的地址: 1
// &g1 = 0x5629b5c59134
// g2 = 0==> &g2 = 0x5629b5c59138
// g3 = 20 ==> &g3 = 0x5629b5c59010 (和前面的两个地址并不连续,跳转到另外一块区域)
// g4 = 40 ==> &g4 = 0x5629b5c59014 (和上面的地址是连续的)
g1 = 20;
cout << "&g1 = " << &g1 << endl; // &g1 = 0x5629b5c59134 没有发生改变
cout << "g2 = 0==> &g2 = " << &g2 << endl;
cout << "g3 = 20 ==> &g3 = " << &g3 << endl;
cout << "g4 = 40 ==> &g4 = " << &g4 << endl;
cout << "static int g6; ==> &g6 = " << &g6 << endl; // 和全局变量区是存在在一块的
cout << "static int g7 = 200; ==> &g7 = " << &g7 << endl;
cout << "static int mg1 = 20;; ==> &mg1 = " << &mg1 << endl; // 和全局变量区是存放在一起的
// 代码区: main() 的地址: 1
// &g1 = 0x55b2c4a81134
// g2 = 0==> &g2 = 0x55b2c4a81138
// g3 = 20 ==> &g3 = 0x55b2c4a81010
// g4 = 40 ==> &g4 = 0x55b2c4a81014
// &g1 = 0x55b2c4a81134
// g2 = 0==> &g2 = 0x55b2c4a81138
// g3 = 20 ==> &g3 = 0x55b2c4a81010
// g4 = 40 ==> &g4 = 0x55b2c4a81014
// static int g6; ==> &g6 = 0x55b2c4a81140
// static int g7 = 200; ==> &g7 = 0x55b2c4a81018
// static int mg1 = 20;; ==> &mg1 = 0x55b2c4a8101c
// 堆和栈的地址空间
int *p1 = new int;
int *p2 = new int;
cout << "堆 p1 = " << p1 << endl;
cout << "堆 p2 = " << p2 << endl;
cout << "栈指针变量 p1 = " << &p1 << endl; // int* 为数据类型 所以 p1 p2 也是栈内存分配的,只是指向的是堆内存空间
cout << "栈指针变量 p2 = " << &p2 << endl;
int i1 = 20;
int i2 = 30;
cout << "栈 i1 = " << &i1 <<endl;
cout << "栈 i2 = " << &i2 <<endl;
// 堆 p1 = 0x556af8ff1280
// 堆 p2 = 0x556af8ff12a0
// 栈指针变量 p1 = 0x7ffdcd51af78
// 栈指针变量 p2 = 0x7ffdcd51af80
// 栈 i1 = 0x7ffdcd51af70
// 栈 i2 = 0x7ffdcd51af74
int arr1[10] = {0};
int* pArr1 = new int[20];
cout << "pArr1 = " << sizeof(pArr1) << endl; // 指针的大小, 因此需要乘以数组的个数
cout << "arr1 = " << sizeof(arr1) << endl; // 所指向的栈空间的大小
delete[] pArr1;
pArr1 = nullptr;
return 0;
}
C++内存分配规则
最新推荐文章于 2023-08-10 20:12:15 发布