当前位置: 首页 > ai >正文

C++ 黑马 内存分配模型

一,   内存分配模型

内存总共有四个分区

1  代码区
主要用来存储二进制代码,由操作系统进行管理

2  栈区
由编译器自己进行释放和分配,例如函数的传递的参数,局部变量,const修饰的局部常量等等....

3  堆区
由程序员自己分配和释放,如果程序员没有进行释放,则由操作系统到最后自行释放

4  全局区
主要存储全局变量,静态常量,字符串常量和全局常量(const修饰)

分区的意义:
不同区域存放不同的数据,可以控制这些数据不同的生命周期,使得内存灵活

二,   代码区和全局区

代码区和全局区是在程序运行之前就已经开始分区了

1. 代码区
主要存放的是CPU执行的机器指令

代码区的特点
1  共享性:在我们点击编译运行按钮的时候都会生成一个可执行的.exe文件,这个文件进行多次点击会弹出多个窗口,然后这里面的数据是互通公用的,计算机并不会重新开辟一个内存再次进行存储

2  只读性:比如充值系统的数据是不可以随意更改的,要是给予更改的话,商家无疑是亏损很大的,所以这个充值系统不可以随意的更改

2. 全局区
主要存放全局变量,静态常量,字符串常量和全局常量(const修饰)
全局变量-----不在函数体内部的变量
静态常量-----加上static关键字的变量
字符串,const修饰的全局常量

以上可以根据设置变量在不同的区域,来输出他们对应的地址来观察判断是否是属于同一区域的

#include<iostream>using namespace std;//全局变量
int a;//const 修饰的全局常量
const int b1 = 0;
const int b2 = 0;int main() {//const修饰的局部变量const int a1 = 0;const int a2 = 0;//static修饰的静态变量static int c1;static int c2;cout << "字符串地址:" << (int)&"hello world" << endl;cout << "static地址:" << (int)&c1 << endl;cout << "static地址:" << (int)&c2 << endl;cout << "const局部地址:" << (int)&a1 << endl;cout << "const局部地址:" << (int)&a2 << endl;cout << "const全局地址:" << (int)&b1 << endl;cout << "const全局地址:" << (int)&b2 << endl;}
字符串地址:995208456
static地址:995221940
static地址:995221944
const局部地址:-2081424876
const局部地址:-2081424844
const全局地址:995208112
const全局地址:995208116D:\porject\C++\x64\Debug\C++.exe (进程 3144)已退出,代码为 0 (0x0)。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

可以看到运行出来的控制窗口显示的地址字符串,static,const修饰的全局地址都是十分接近的,但是const修饰的局部地址是离很远的,这么说明const修饰的局部变量不是在全局区

三,栈区和堆区

栈区和堆区,这两个区域是程序运行后才产生的

1. 栈区

栈区是由编译器自己分配和释放的,一般都是局部变量,函数的传参值...
注意事项:1  不要返回局部变量的地址,栈区开辟的数据由编译器自己决定释放

#include<iostream>using namespace std;int* fun() {int b = 10;return &b;
}int main() {int* p = fun();cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;int a = 1;cout << *p << endl;return 0;
}

当我们不用VS2022,用Dev-C++来运行这个代码的时候,运行出来的结果是这样的

10
0
0
0
0
0
0--------------------------------
Process exited after 0.791 seconds with return value 0
请按任意键继续. . .

运行出来的结果后面都是未知量,这个时候我们可以知道,经典的C++编译器只会给我们保留一次这个值,并不会一直保留,所以后面答应出来的值都是0

2. 堆区

堆区的知识点我们只需要知道,这个区域是我们程序员自己去释放和开辟区域的,然后C++喜欢用new运算符来进行开辟内存和释放内存

new运算符的使用
1.  利用new运算符开辟一个变量并且赋值

int* p = new int(10);
delete p;

2.  利用new运算符开辟一个数组

int* p = new int[10];
delete []p;

四,  总结

1  内存的分区类型

1 栈区  2 代码区  3 全局区  4 堆区

2  每个内存分区的作用
(づ。◕‿‿◕。)づ  代码区:
(a)  主要存放二进制的机器指令
(b)  两个特点:共享和只读特性

(ノ◕ヮ◕)ノ:・゚✧   全局区:
(a)  主要存放全局变量,静态常量,const修饰的全局常量,需要注意的是const修饰的常量不是存放在全局区域,可以通过打印对应的地址来判断他们的分区是否一致

(。・ω・。)ノ♡       栈区:
(a)  栈区主要是编译器自己进行释放和分配内存,常见的由函数传递的参数,局部变量...等一系列生命周期较短的变量

Σ(°△°|||)︴        堆区:
(a)  堆区主要是程序员自己进行分配和释放内存,最后没有释放的内存,等到程序结束由操作系统进行释放内存

3  new操作运算符的使用
主要就是分配变量和数组在堆区

int* p = new int(10);
delete p;
int* p = new int[10];
delete []p;
http://www.xdnf.cn/news/17388.html

相关文章:

  • 通过trae开发你的第一个Chrome扩展插件
  • 2025年APP开发趋势:4大方向重构行业格局
  • [激光原理与应用-224]:机械 - 机械设计与加工 - 常见的术语以及含义
  • python | numpy小记(十):理解 NumPy 中的 `np.random.multinomial`(进阶)
  • 医学统计(随机对照研究分类变量结局数据的统计策略2)
  • 面对信号在时频平面打结,VNCMD分割算法深度解密
  • 【接口自动化】-5- 接口关联处理
  • 比特币现货和比特币合约的区别与联系
  • 金融机构在元宇宙中的业务开展与创新路径
  • nginx+lua+redis案例
  • AI智能编程工具汇总
  • Numpy基础(通用函数)
  • [IOMMU]基于 AMD IOMMU(AMD‑Vi/IOMMUv2)的系统化总结与落地方案
  • 【C++】模版进阶
  • FMS 2025存储峰会获奖技术全景解读
  • C/C++基础详解(二)
  • AcWing 4579. 相遇问题
  • Day38 Dataset和Dataloader类
  • Datawhale AI夏令营-记录2
  • NVIDIA Jetson实战笔记
  • 【c++】探秘Loop机制:C++中优雅的双向数据交互模式
  • 力扣 hot100 Day70
  • 【Python 高频 API 速学 ⑥】
  • CrystalDiskInfo 9.0.1 安装教程 - 硬盘检测工具下载安装步骤详解
  • 基于迁移学习的伺服电机轴承故障诊断
  • Python变量引用拷贝
  • 求和算法的向后稳定性 backward stable
  • 大模型“涌现”背后的暗线——规模、数据、目标函数的三重协奏
  • Spring 的原理探究
  • 服务器硬件电路设计之I2C问答(二):I2C总线的传输速率与上拉电阻有什么关系?