十一、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.mzph.cn/news/656046.shtml

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

相关文章

qt5-入门

参考&#xff1a; qt学习指南 Qt5和Qt6的区别-CSDN博客 Qt 学习之路_w3cschool Qt教程&#xff0c;Qt5编程入门教程&#xff08;非常详细&#xff09; 本地环境&#xff1a; win10专业版&#xff0c;64位 技术选择 Qt5力推QML界面编程。QML类似HTML&#xff0c;可以借助CSS进…

【超详细教程】GPT-SoVITs从零开始训练声音克隆教程(主要以云端AutoDL部署为例)

目录 一、前言 二、GPT-SoVITs使用教程 2.1、Windows一键启动 2.2、AutoDL云端部署 2.3、人声伴奏分离 2.4、语音切割 2.5、打标训练数据 2.6、数据集预处理 2.7、训练音频数据 2.8、推理模型 三、总结 一、前言 近日&#xff0c;RVC变声器的创始人&#xff08;GitH…

Linux——Ubuntu安装MySQL并设置远程登录

1、安装mysql8.0.35 1.更新包列表&#xff0c;首先&#xff0c;确保您的系统已更新到最新状态。运行以下命令来更新包列表和安装最新的软件包&#xff1a; sudo apt update sudo apt upgrade2.安装MySQL服务器&#xff1a;运行以下命令来安装MySQL服务器&#xff1a; sudo a…

【C++】this指针

this指针&#xff01; 目录 this指针的引出&#xff1a;从C语言中理解this指针&#xff1a; this指针的特性&#xff1a;练习&#xff1a; this指针的引出&#xff1a; 我们知道&#xff0c;类中的成员函数是有专门的存放区&#xff1a;公共代码区&#xff0c;这也就意味着我…

方案:将vue项目放在SpringMVC中,并用tomcat访问

需要先将项目生成一次war包才能访问项目的webapp文件夹下的资源&#xff0c;否则tomcat的webapp文件夹下面不会生成对应资源文件夹就无法访问。 问题&#xff1a;目录如下&#xff1a; 今天我测试了一下将vue打包后&#xff0c;放入webapp下面访问&#xff0c;却发现vue项目无…

第九节HarmonyOS 常用基础组件13-TimePicker

1、描述 时间选择组件&#xff0c;根据指定参数创建选择器&#xff0c;支持选择小时以及分钟。默认以24小时的时间区间创建滑动选择器。 2、接口 TimePicker(options?: {selected?: Date}) 3、参数 selected - Date - 设置选中项的时间。默认是系统当前的时间。 4、属性…

软件工程学科的本质

软件工程学科的本质是分析与设计&#xff0c;是画图&#xff0c;是进行软件架构设计&#xff0c;进行进行软件项目管理。而非写代码。 分析有结构化分析&#xff0c;面向对象分析法&#xff0c;都用图来描述表达。 设计有结构化设计&#xff0c;面向对象设计法&#xff0c;都…

云计算运维 · 第三阶段 · git

学习b记 第三阶段 三、持续集成 1、git #安装 yum -y install git[rootgit-git ~]# git config –-global user.name "qxl" # 配置git使用用户 [rootgit-git ~]# git config –-global user.email "qxlmail.com" # 配置git使用邮箱 [rootgit-git ~]# g…

面试题 02.07. 链表相交(力扣LeetCode)

文章目录 面试题 02.07. 链表相交题目描述解题思路c代码优化后c代码 面试题 02.07. 链表相交 题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 …

java代码中直接调用存储过程

开启数据库语句批处理 url: jdbc:mysql://192.168.0.xxx:3306/xxx?useSSLfalse&useUnicodetrue&characterEncodingutf-8&zeroDateTimeBehaviorCONVERT_TO_NULL&serverTimezoneUTC&allowMultiQueriestrue 重点&#xff1a; allowMultiQueriestrue mysql…

医疗保健和生命科学组织的远程访问解决方案

医疗保健和生命科学组织的远程访问解决方案——随时随地为医疗保健和生命科学人员提供相关信息 引领生命科学远程工作的IT新高度 生命科学组织一直承受着改进工作流程、降低成本和比以往更快地交付产品的压力。 使用远程访问和集中式 IT 基础架构&#xff0c;企业可以在加快上…

Linux CPU 负载说明

一、背景 工作中我们经常遇到CPU 负载高&#xff0c;CPU负载高意味着什么&#xff1f; CPU的负载是怎么计算的&#xff1f; top指令中的各个指标代表什么含义&#xff1f; 二、CPU 负载计算方法 在系统出现负载问题&#xff0c;通常会使用uptime和top确认负载&#xff0c;这两…

基于C#制作一个连连看小游戏

基于C#制作一个连连看小游戏,实现:难易度选择、关卡选择、倒计时进度条、得分计算、音效播放等功能。 目录 引言游戏规则开发环境准备游戏界面设计游戏逻辑实现图片加载与显示鼠标事件处理游戏优化与扩展添加关卡与难度选择说明</

备战蓝桥杯--数据结构及STL应用(基础)

今天轻松一点&#xff0c;讲一讲stl的基本操作吧&#xff01; 首先&#xff0c;让我们一起创建一个vector容器吧&#xff01; #include<bits/stdc.h> using namespace std; struct cocoack{ int coco,ck; } void solve(){vector<cocoack> x;for(int i0;i<5;i){…

Java链表(2)

&#x1f435;本篇文章将对双向链表进行讲解&#xff0c;模拟实现双向链表的常用方法 一、什么是双向链表 双向链表在指针域上相较于单链表&#xff0c;每一个节点多了一个指向前驱节点的引用prev以及多了指向最后一个节点的引用last&#xff1a; 二、双向链表的模拟实现 首先…

C++不能直接返回数组

文章目录 前言一、缘由二、示例&#xff1a;函数返回后&#xff0c;指针指向无效内存三、解决方案3.1、动态分配数组3.2、使用 std::vector&#xff1a;&#xff08;最为推荐&#xff09;3.3、使用静态数组&#xff1a; 前言 在 C 中&#xff0c;不能直接返回一个数组。因为数组…

STL:list实现

list是和vector类似的顺序型容器&#xff0c;也是是比vector更为复杂的容器。list是双向带头链表&#xff0c;初始有一个不存数据的头节点&#xff0c;并通过节点内指针将后续节点依次连接起来 。 相较于vector&#xff0c;list特点如下&#xff1a; (1)list可以按需申请&…

使用Docker安装Jenkins,并能够在该Jenkins中使用Docker

1. 构建Dockerfile 试错1 参考https://medium.com/manav503/how-to-build-docker-images-inside-a-jenkins-container-d59944102f30 按照文章里所介绍的&#xff0c;实现在Jenkins容器环境中依然能够调用Docker&#xff0c;需要做到以下几步 下载Jenkins镜像将环境中的docke…

CGAL 网格剖分算法

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 CGAL为我们提供了一种网格剖分算法,它与之前的网格平面分割算法有些类似,只不过它输出的是平面与网格的相交线段,CGAL也为我们提供了一种加速策略(AABB树)。 二、实现代码 #include <iostream> #includ…