十一、C++核心编程(1)内存分区模型

本阶段主要针对面向对象程技术做详细讲解,探讨C++中的核心和精髓。

一、内存分区模型

1、C++程序在执行时,将内存大方向划分为4个区域:

  1. 代码区:存放函数体的二进制代码,由操作系统进行管理的
  2. 全局区:存放全局变量和静态变量以及常量
  3. 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
  4. 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

2、内存四区意义:

不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

3、程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前运行前分为两个区域

代码区:

  • 存放 CPU 执行的机器指令
  • 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
  • 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:

  • 全局变量静态变量存放在此
  • 全局区还包含了常量区,字符串常量和其他常量也存放在此
  • 该区域的数据在程序结束后由操作系统释放
#include<iostream>
#include<string.h>
using namespace std;
//全局变量
int g_a = 10;
int g_b = 10;//const修饰的全局变量,全局常量
const int c_g_a = 10;int main()
{//全局区//全局变量、静态变量、常量//创建普通局部变量int a = 10;int b = 10;cout << "局部变量a的地址为:" << (int)&a << endl;cout << "局部变量a的地址为:" << (int)&b << endl;cout<<"全局变量g_a的地址为:" << (int)&g_a << endl;cout << "全局变量g_b的地址为:" << (int)&g_b << endl;//看地址开头不一样,说明局部变量和全局变量不在一个段中//常量//字符串常量cout<< "字符串常量的地址为:"<<(int)&"hello world" << endl;//const修饰的变量//const修饰的全局变量,const修饰的局部变量cout << "全局常量c_g_a的地址为:" << (int)&c_g_a << endl;const int c_l_a = 10;		//c-const	g-globe		a-localconst int c_l_b = 10;cout<<"局部常量c_l_a的地址为:"<<(int)&c_l_a << endl;cout << "局部常量c_l_b的地址为:" << (int)&c_l_b << endl;system("pause");return 0;
}

运行结果: 

局部变量a的地址为:16186896
局部变量a的地址为:16186884
全局变量g_a的地址为:6668356
全局变量g_b的地址为:6668360
字符串常量的地址为:6658884
全局常量c_g_a的地址为:6659084
局部常量c_l_a的地址为:16186872
局部常量c_l_b的地址为:16186860

总结:

  1. C++中在程序运行前分为全局区和代码区
  2. 代码区特点是共享和只读
  3. 全局区中存放全局变量、静态变量、常量
  4. 常量区中存放const修饰的全局常量 和 字符串常量 

二、程序运行后

1、栈区:

由编译器自动分配释放,存放函数的参数值,局部变量等

注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放 

#include<iostream>
#include<string.h>
using namespace std;//栈区数据注意事项 --不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放int * func()    //形参也会存放在栈区
{int a = 10;		//局部变量,存放在栈区,栈区的数据在函数执行完后自动释放return &a;		//返回局部变量的地址
}
int main()
{//接收func函数的返回值int * p = func();cout << *p << endl;cout << *p << endl;		//第一次可以打印10,然后释放内存,第二次打印的是乱码system("pause");return 0;
}

 运行结果:

10
1490389104

2、堆区:

由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

在C++中主要利用new在堆区开辟内存

#include<iostream>
#include<string.h>
using namespace std;
int* func()
{//利用new关键字可以将数据开辟到堆区int * p = new int(10);return p;
}
int main()
{//在堆区开辟数据//指针 本质也是局部变量,放在栈上,指针保存的数据是放在堆区int * p = func();cout << *p << endl;cout << *p << endl;cout << *p << endl;cout << *p << endl;//均能打印,说明堆区是由程序员控制的,不会由系统自动释放system("pause");return 0;
}

运行结果:

10
10
10
10

三、new操作符

C++中利用new操作符在堆区开辟数据

堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete

语法:

new 数据类型

利用new创建的数据,会返回该数据对应的类型的指针

#include<iostream>
#include<string.h>
using namespace std;//1、new的基本语法
int * func()
{//在堆区创建整型数据//new返回的是该数据类型的指针int * p = new int(10);return p;
}void test01()
{int* p = func();cout << *p << endl;cout << *p << endl;cout << *p << endl;//多次输出不会出现乱码//堆区的数据 由程序员管理开辟,程序员管理释放//如果想释放堆区的数据利用关键字 deletedelete p;//cout << *p << endl;	//内存已经被释放,再次访问就是非法操作,会报错
}//2、在堆区利用new开辟数组
void test02()
{//创建10个整型数据的数组,在堆区int * arr = new int[10];for (int i = 0; i < 10; i++){arr[i] = i + 100;	//给十个元素赋值100~109}for (int i = 0; i < 10; i++){cout<< arr[i]<< endl;}//释放堆区数组//释放数组的时候,要加[]才可以delete[] arr;
}int main()
{test01();cout << endl;test02();system("pause");return 0;
}

 运行结果:

10
10
10100
101
102
103
104
105
106
107
108
109

以下为非法输出,因为p的内存已经被释放 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439746.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用PowerBI 基于Adventure Works案例分析

Adventure Works案例分析 前言 数据时代来临&#xff0c;但一个人要顺应时代的发展是真理。 数据分析的核心要素 那数分到底是什么&#xff1f; 显然DT 并不等同于 IT&#xff0c;我们需要的不仅仅是更快的服务器、更多的数据、更好用的工具。这些都是重要的组成部分&…

基于ldap实现登录认证

最近开发的应用需要外协人员实现登录认证&#xff0c;外协人员的密码等信息已经录入到ldap, 需要连接ldap进行登录认证。下面先介绍一下登录的网络旅程图。 一.nginx实现AES加密 nginx请求处理入口&#xff08;前端请求为json格式&#xff09; location /aes {default_type te…

this.$store undefined

报错&#xff1a;vuex报错 this.$store显示undefined&#xff0c;可能存在的问题&#xff0c;从以下几个方向排查 1、查看store文件中的vuex实例对象是否暴漏 2、main.js中是否注入store 3、如果上边均没问题&#xff0c;打开package.json&#xff0c;查看vue与vuex的版本&am…

系列五十、idea父子项目忽略部分文件

一、idea父子项目忽略部分文件 **/mvnw **/mvnw.cmd **/.mvn **/target/ .idea **/.gitignore

电商API接口的应用|电商跨境电商商品采集高效解决方案

电商API接口的应用|电商跨境电商商品采集高效解决方案 面对数十万亿元的跨境电商市场&#xff0c;以阿里巴巴国际站为代表的跨境电商数字平台&#xff0c;在政策、需求以及供应链的驱动下&#xff0c;为中小企业提供了全产业链、全供应链一体化综合服务&#xff0c;让越来越多…

Ansys Lumerical | 闪耀光栅

附件下载 联系工作人员获取附件 此示例说明如何计算闪耀光栅的光栅阶数。该光栅在每个波长处都有许多光栅阶数。为了捕获全反射和透射的特征&#xff0c;监视器中需要更多的频率点。 模拟设置 上面的仿真文件中显示了闪耀光栅。它由低折射率 &#xff08;1.4&#xff09; 基…

红黑树封装实现STL-map、set

利用红黑树作为模板封装的思路 将红黑树作为一个基础的类模板&#xff0c;通过给这个类模板传递不同的参数&#xff0c;从而控制它所实现的容器。 最主要的点是用自己的map和set通过传递不同的模板参数控制红黑树第二个模板参数 T 来确定传入的到底是 Key 还是 pair<Key, …

Java异常处理集合

Java异常处理 Java语言在执行后会中断&#xff0c;也就是在出错位置后的代码都不会被执行&#xff0c;为了使非致命错误后的程序仍然能够执行&#xff0c;引入异常处理机制。 异常 可处理的异常用Exception表示&#xff0c;不可处理的异常用Error表示&#xff0c;通常是栈内…

探索数字经济:从基础到前沿的奇妙旅程

新一轮技术革命方兴未艾&#xff0c;特别是以人工智能、大数据、物联网等为代表的数字技术革命&#xff0c;催生了一系列新技术、新产业、新模式&#xff0c;深刻改变着世界经济面貌。数字经济已成为重组全球要素资源、重塑全球经济结构、改变全球竞争格局的关键力量。预估到20…

儿童写字用什么台灯比较好?学生专用台灯第一品牌

现在孩子的生活比我们小学时候更加丰富多彩&#xff0c;当然也更“忙”了起来&#xff01;正是因为上学之后&#xff0c;有了这么多的学习任务&#xff0c;所以孩子的桌面空间使用频率越来越高&#xff01;为了让孩子更好地完成学习任务&#xff0c;以及保护视力。越来越多家长…

BUUCTF misc 二维码

目录 将Windows中的文件传输到Linux虚拟机中 binwalk用法 kali-linux中使用fcrackzip工具爆破zip密码 打开题目&#xff1a; 下载并解压后&#xff0c;得到一张二维码图片&#xff0c;我们使用 toolhelper.cn 里的二维码解析小工具查看得到&#xff1a; 可以看到 secret is …

led护眼灯真的能护眼吗安全吗?护眼又安全的LED灯推荐

近些年来&#xff0c;中国患近视的孩子越来越多&#xff0c;为了让孩子在家写作业时眼睛少受损伤&#xff0c;很多家长专门准备了LED台灯。但不合格LED灯反而加剧孩子们视力疲劳&#xff0c;甚至出现近视。其中重要一个原因是某些LED灯存在着严重的频闪&#xff0c;长期在这样的…