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

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.dtcms.com/a/324817.html

相关文章:

  • 详解Windows(十六)——计划任务
  • Linux安装Jenkins-2.432,jdk17
  • Day11 原理篇
  • 华为防火墙配置指南【附实战案例】
  • python urllib模块怎么使用
  • 【软件测试】概念篇 — 详解
  • 广东省省考备考(第七十二天8.10)——言语理解与表达、判断推理(强化训练)
  • APISIX 路由优先级
  • SupChains团队:化学品制造商 ChampionX 供应链需求预测案例分享(十七)
  • 托福阅读记录
  • TypeScript 中的as const是什么?
  • 基于Actor-Critic策略的Atari中的pong_v3
  • 机器学习第八课之K-means聚类算法
  • 零基础学编程,编程从入门到精通系列教程,附:编程工具箱之公用事件的用法#零基础学编程从哪里开始#新手学编程先学什么#公用事件构件编程用法
  • Lua语言变量、函数、运算符、循环
  • 小学数学计算技巧全攻略
  • 攻击者瞄准加密技术的基础:智能合约
  • [网安工具] Web 漏洞扫描工具 —— GoBy · 使用手册
  • Video Lecture 8 Page Fault
  • 7、西门子PLC基础术语:数据单位、存储区域、寻址方式、字节序
  • LightGBM 与 GBDT 在机器学习中的性能与特点比较
  • element-ui el-progress在有小数的情况下,会换行显示。解决不换行的问题。
  • redis集群-本地环境
  • 【前端基础】14、CSS设置背景(background相关的)
  • 正则表达式常用语法参考
  • STM32H7 以太网配置引申的内存问题
  • A2A协议深度理解与实践
  • 解决 .NET Core 6.0 + PostgreSQL 网站首次连接缓慢问题
  • 安全生产基础知识(一)
  • 去除Edge微软浏览器与Chrome谷歌浏览器顶部出现“此版本的Windows不再支持升级Windows 10”的烦人提示