c++ 内存分析模型、引用

 一、内存模型分区

内存四区的意义:

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

(一)程序运行前

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

代码区:

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

全局区:

  • 全局变量和静态变量存放在此
  • 全局区还包含了常量区,字符串常量和其他常量也存放在此
  • 该区域的数据在程序结束后由操作系统释放

#include<iostream>
using namespace std;
int g_a = 10;
int g_b = 10;
//const修饰的全局变量,全局常量
int c_g_a = 10;
int c_g_b= 10;
int main()
{
//全局区
//全局变量、静态变量、常量

//创建普通局部变量
int a = 10;
int b = 20;
cout << "局部变量a的地址为:" << (int)&a << endl;
cout << "局部变量a的地址为:" << (int)&b << endl;
cout << "全局变量g_a的地址为:" <<(int)&g_a << endl;
cout << "全局变量g_b的地址为:" <<(int)&g_b << endl;
//创建静态变量
static int s_c = 10;
static int s_d = 10;
cout << "静态变量s_c的地址为:" << (int)&s_c << endl;
cout << "静态变量s_d的地址为:" << (int)&s_d << endl;

//常量
//字符串常量
cout<<"字符串常量的地址为:"<<(int) & "hello world"<<endl;
//const修饰的变量
//const 修饰的全局变量 
// const修饰的局部变量
const int c_l_a = 10;
const int c_l_b = 10;
cout << "const修饰的全局常量c_g_a的地址为:" << (int)&c_g_a << endl;
cout << "const修饰的全局常量c_g_b的地址为:" << (int)&c_g_b << endl;
cout << "const修饰的局部变量c_l_a的地址为:" << (int)&c_l_a << endl;
cout << "const修饰的局部变量c_l_b的地址为:" << (int)&c_l_b << endl;
system("pause");
return 0;

}
#include <iostream>
using namespace std;
//栈区数据的注意事项 ---不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放

int* func(int b) {//形参数据也会放在栈区
	b = 200;
	int a = 10;//局部变量 存放在栈区,栈区的数据在函数执行完后自动释放
	return  & a;//返回局部变量的地址

}
int main() {
	//接受func函数的返回值
	int *p = func(1);
	cout << "p = " << *p << endl;
	cout << "p = " << *p << endl;
	
	system("pause");
	return 0;
}

(二)程序运行后

栈区:

  • 由编译器自动分配释放,存放函数的参数值,局部变量等
  • 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
#include <iostream>
using namespace std;
//栈区数据的注意事项 ---不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放

int* func(int b) {//形参数据也会放在栈区
	b = 200;
	int a = 10;//局部变量 存放在栈区,栈区的数据在函数执行完后自动释放
	return  & a;//返回局部变量的地址

}
int main() {
	//接受func函数的返回值
	int *p = func(1);
	cout << "p = " << *p << endl;
	cout << "p = " << *p << endl;
	
	system("pause");
	return 0;
}

堆区:

  • 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收
  • 在c++中主要利用new在堆区开辟内存
#include<iostream>
using namespace std;

int * func() {
	//利用new关键字 可以将数据开辟到堆区
	//指针 本质也是局部变量,放在栈上,指针保存的数据是放在堆区
	int * p = new int(10);
	return p;

}

int main() {
	//在堆区开辟数据
	int *p=func();
	cout << "p=" << *p << endl;
	system("pause");
	return 0;
}

 

(三)new操作符

  • c++中利用new操作符在堆区开辟数据
  • 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete
  • 语法: new 数据类型
  • 利用new创建的数据,会返回该数据对应的类型的指针

没有进行delete清除时

 使用delete进行清除后

#include <iostream>
using namespace std;
//1、new的基本语法
int* func() {
	//在堆区创建整形数据
	//new返回的是一个该数据类型的指针
	int *p = new int(10);
	return p;

}
//2、在堆区利用new开辟数组
void test02() {
	//创建10整型数据的数组,在堆区
int * arr=	new int[10];//10代表数组有10个元素
for (int i = 0; i < 10; i++)
{
	arr[i] = i + 100;
}
for (int i = 0; i < 10; i++) {
	cout << arr[i] << endl;
}
//释放数组的内存空间
delete[] arr; //释放数组需要加[]
}
void test01()
{
	int* p = func();
	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;
	//堆区的数据 由程序员管理开辟,程序员管理释放
	//利用关键字delete释放堆区数据
	delete p;

}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;

}

二、引用

(一)引用的基本使用

作用:给变量起别名

语法:数据类型 &别名=原名

#include<iostream>
using namespace std;

int main() {
	//引用的基本语法
	//数据类型 &别名 =原名
	int a = 10;
	int& b = a; //b是a的引用
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	b = 20; //修改b的值,a也会跟着变化
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;


	system("pause");
	return 0;

}

(二)引用的注意事项

  • 引用必须初始化
  • 引用在初始化后,不可以改变

#include<iostream>
using namespace std;
int main()
{
	int a = 10;
	//1、引用必须初始化
	//int& b; //错误,必须要初始化
	int& b = a;

	//2、引用在初始化后,不可以改变
	int c = 20;
	b = c;//赋值操作而不是更改引用
	cout << "a=" << a << endl; //输出20
	cout << "b=" << b << endl; //输出20
	cout << "c=" << c << endl; //输出20

	//3、引用的本质是指针,因此可以直接操作指针指向的内存空间
	system("pause");
	return 0;

}

(三)引用做函数参数

  • 作用:函数传递时,可以利用引用的技术让形参修饰实参
  • 优点:可以简化指针修改实参
#include <iostream>
using namespace std;
//交换函数

//1.值传递
void mySwap01(int a,int b) {
	int temp = a;
	a = b;
	b = temp;
}
//2.地址传递
void mySwap02(int* a, int* b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}
//3.引用传递
void mySwap03(int &a, int &b) {
	int temp = a;
	a =b;
	b = temp;
}

int main() {
	int a = 10, b = 20;
	cout << "a = " << a << " b = " << b << endl;
	mySwap01(a, b);//值传递 形参不会修饰实参
	cout << "a = " << a << " b = " << b << endl;
	mySwap02(&a, &b);//地址传递 形参会修饰实参
	cout << "a = " << a << " b = " << b << endl;
	mySwap03(a, b);//引用传递 形参会修饰实参
	cout << "a = " << a << " b = " << b << endl;
	system("pause");
	return 0;
}

(四)引用做函数返回值

作用:引用是可以作为函数的返回值存在

注意:不要返回局部变脸引用

用法:函数调用作为左值

#include <iostream>
using namespace std;
//引用做函数的返回值

//1.不要返回局部变量的引用
int& test01() {
	int a = 10;
	return a; //错误,局部变量的引用不能作为函数的返回值
}

//2.函数的调用可以作为左值
int & test02() {
	static int a = 10;//静态变量(全局变量)
	return a;
}

int main() {
	int & ref = test01();
	cout << ref << endl; //第一次结果正确,是因为编译器做了保留
	cout <<"ref="  << ref << endl;//第二次结果错误,是因为a的内存已经释放
	cout << ref << endl;
	cout << ref << endl;
	cout << ref << endl;
	cout << ref << endl;

	int &ref2 = test02();
	cout << ref2 << endl;
	cout << ref2 << endl;
	cout << ref2 << endl;
	test02() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
	cout << "ref2=" << ref2 << endl;
	cout << "ref2=" << ref2 << endl;
	cout << "ref2=" << ref2 << endl;

	system("pause");
	return 0;
}

(五)引用的本质

本质:引用的本质在c++内部实现是一个指针常量

#include <iostream>
using namespace std;
//发现是引用,转换为int * const ref=&a;
void func(int &ref) {
	ref = 100;//ref是引用,转换为 *ref=100

}

int main() {
	int a = 10;
	//自动转换为 int * const ref=&a; 指针常量是指针指向不可改,也说明了引用不可更改
	int &ref = a; 
	ref = 20;//内部发现ref是引用,自动帮我们转换为:*ref=20;
	cout << "a=" << a << endl; //a=20
	cout << "ref=" << ref << endl;

	system("pause");
	return 0;
}

(六)常量引用

作用:常量引用主要用来修饰形参,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

不加const修饰 

#include <iostream>

using namespace std;
//打印数据的函数
void showValue( int & val){
	val = 1000;
	cout << "value =" << val << endl;
}
int main() {
	//常量引用
	//使用场景 用来修饰形参,防止误操作
	int a = 10;
	//加上const之后 编译器将代码修改 int temp=10;const int &ref=temp;

	const int& ref = 10;//引用必须引一块合法的内存空间
	//ref = 20;//加入const之后变为只读,不可以修改
	cout << "ref =" << ref << endl;
	int b = 100;
	showValue(b);//调用函数传递引用
	system("pause");
	return 0;
}

加入const修饰

#include <iostream>

using namespace std;
//打印数据的函数
void showValue(const int & val){
	//val = 1000; //加入const 后会报错 不能修改
	cout << "value =" << val << endl;
}
int main() {
	//常量引用
	//使用场景 用来修饰形参,防止误操作
	int a = 10;
	//加上const之后 编译器将代码修改 int temp=10;const int &ref=temp;

	const int& ref = 10;//引用必须引一块合法的内存空间
	//ref = 20;//加入const之后变为只读,不可以修改
	cout << "ref =" << ref << endl;
	int b = 100;
	showValue(b);//调用函数传递引用
	system("pause");
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 89 之 string查找和替换

#include <iostream> #include <string> using namespace std;int main() { // int find(const string& str, int pos 0) const; //查找str第一次出现位置,从pos开始查找 // int find(const char* s, int pos 0) const; //查找s第一次出现位置,从pos开始查找…

【单片机毕业设计选题24020】-全自动鱼缸的设计与应用

系统功能: &#xff08;1&#xff09;检测并控制鱼缸水温&#xff0c;水温低于22℃后开启加热&#xff0c;高于28℃后关闭加热。 &#xff08;2&#xff09;定时喂食&#xff0c;每天12点和0点喂食一次&#xff0c;步进电机开启后再关闭模拟喂食。 &#xff08;3&#xff09…

路由器基础配置以及静态路由配置

1、搭建网络 搭建网络拓扑、分配IP地址、划分网段、连接端口 2、配置路由器 路由器基础配置 //进入全局配置模式 Router#enable Router#conf t Enter configuration commands, one per line. End with CNTL/Z.//配置高速同步串口serial2/0 Router(config)#int ser2/0 Route…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-27含并行连结的网络GoogLeNet

27含并行连结的网络GoogLeNet import torch from torch import nn from torch.nn import functional as F import liliPytorch as lp import matplotlib.pyplot as pltclass Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, …

JDK19特性

JDK19特性 一、JAVA19概述 JDK 19 2022 年 9 月 20 日正式发布以供生产使用,非长期支持版本。不过,JDK 19 中有一些比较重要的新特性值得关注。 JDK 19 只有 7 个新特性: JEP 405: Record Patterns(记录模式)[1] (预览)JEP 422: Linux/RISC-V Port[2]JEP 424: Foreign …

Eclipse快捷键大全

CtrlK 参照选中的Word快速定位到下一个 CtrlE 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示) Ctrl/(小键盘) 折叠当前类中的所有代码 Ctrl(小键盘) 展开当前类中的所有代码 CtrlSpace 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的…

Open WebUI – 本地化部署大模型仿照 ChatGPT用户界面

Open WebUI介绍&#xff1a; Open WebUI 是一个仿照 ChatGPT 界面&#xff0c;为本地大语言模型提供图形化界面的开源项目&#xff0c;可以非常方便的调试、调用本地模型。你能用它连接你在本地的大语言模型&#xff08;包括 Ollama 和 OpenAI 兼容的 API&#xff09;&#xf…

牛顿迭代法(求解整数的近似平方根)

情景再现 面试官&#xff1a;给你一个整数怎样最快求解他的近似平方根&#xff1f; 小白&#xff1a;可以用while循环呀&#xff01; 面试官&#xff1a;有没有更好的方法&#xff1f; 小白&#xff1a;可以从这个数的左右两边开始迭代。 面试官&#xff1a;除了这个呢&#xf…

Flutter第十二弹 Flutter多平台运行

目标&#xff1a; 1.在多平台调试启动Flutter程序运行 一、安卓模拟器 1.1 检查当前Flutter适配的版本 flutter doctor提供了Flutter诊断。 $ flutter doctor --verbose /Users/zhouronghua/IDES/flutter/bin/flutter doctor --verbose [✓] Flutter (Channel master, 2.1…

操作系统:高效、稳定的承上启下

标题&#xff1a;操作系统&#xff1a;高效、稳定的承上启下 水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 一、初识操作系统 第一个操作系统&#xff1a;Uinx Uinx的商业化 Linux&#xff1a;横空出世 二、如何在Windows上使用Linux 正文开始&#xff1a;…

打工人的PPT救星来了!用这款AI工具,10秒生成您的专属PPT

今天帮同事解决了一个代码合并的问题。其实问题不复杂&#xff0c;要把1的代码合到2的位置&#xff1a; 这个处理方式其实很简单&#xff0c;使用 “git cherry-pick hash值” 就可以。 同事直接对我赞许有加&#xff0c;不曾想被领导看到了&#xff0c;对我说了一句&#xff…

Tampermonkey油猴 跨域请求下载图片示例

Tampermonkey油猴 跨域请求下载图片示例 前言项目目标网站代码编写 运行效果 前言 需要用油猴采集并下载一个网站的图片&#xff0c;直接下下不了&#xff0c;搜了一下&#xff0c;是禁止跨域&#xff0c;使用CORS Unblock也不行&#xff0c;所以使用油猴自带的GM_xmlhttpRequ…

The First项目报告:解读互链操作协议LayerZero

随着 DeFi 项目的兴起&#xff0c;跨链互操作性成为区块链领域的热门话题&#xff0c;在众多的跨链平台中&#xff0c;Layer Zero 凭借其创新技术和设计备受关注&#xff0c;近期Layer Zero发布代币空投方案&#xff0c;引发社区热议&#xff0c;随着其代币上线The First平台&a…

【STM32入门学习】学习嵌入式实时操作系统(RTOS)移植uc/OS到stm32F103上

目录 一、建立STM32HAL库工程 1.1实时操作系统 1.2基于HAL库创建工程 二、获取uC/OS-III源码 三、移植准备 3.1复制uC/OS-III文件到工程文件夹 3.2添加工程组件和头文件路径 四、移植修改代码 &#xff14;.1.启动文件修改&#xff1a; &#xff14;.2.app_cfg.h &a…

【数据结构】线性表之《栈》超详细实现

栈 一.栈的概念及结构二.顺序栈与链栈1.顺序栈2.链栈1.单链表栈2.双链表栈 三.顺序栈的实现1.栈的初始化2.检查栈的容量3.入栈4.出栈5.获取栈顶元素6.栈的大小7.栈的判空8.栈的清空9.栈的销毁 四.模块化源代码1.Stack.h2.Stack.c3.test.c 一.栈的概念及结构 栈&#xff1a;一种…

Azure vs. AssemblyAI:深度解析语音转文本服务的对决

在技术飞速发展的今天&#xff0c;API已成为连接不同软件和服务的关键桥梁。对于需要语音转文本功能的应用&#xff0c;我们对比了两个广受欢迎的API接口&#xff1a;Azure 语音转文本和AssemblyAI AI语音转文本。 Azure 语音转文本 Azure 语音转文本提供快速、准确的语音转文本…

ArrayList知识点(面试)

上一篇我们说了hashmap的相关知识点&#xff0c;这一篇我们再说一些ArrayList的相关知识&#xff0c;因为ArrayList也是我们项目中比较常用的。 ArrayList(底层是数组) 底层工作原理 首先&#xff0c;在构造ArrayList的时候会先看有没有指定容量&#xff0c;如果没有&#xf…

音视频开发29 FFmpeg 音频编码- 流程以及重要API,该章节使用AAC编码说明

此章节的一些参数&#xff0c;需要先掌握aac的一些基本知识&#xff1a;​​​​​​aac音视频开发13 FFmpeg 音频 --- 常用音频格式AAC&#xff0c;AAC编码器&#xff0c; AAC ADTS格式 。_ffmpeg aac data数据格式-CSDN博客 目的&#xff1a; 从本地⽂件读取PCM数据进⾏AAC格…

FL论文专栏|设备异构、异步联邦

论文&#xff1a;Asynchronous Federated Optimization&#xff08;12th Annual Workshop on Optimization for Machine Learning&#xff09; 链接 实现Server的异步更新。每次Server广播全局Model的时候附带一个时间戳&#xff0c;Client跑完之后上传将时间戳和Model同时带回…

【办公类-50-01】20240620自主游戏观察记录表19周内容打乱

背景需求&#xff1a; 又到了期末&#xff0c;各种班级资料需要提交。 有一份自主游戏观察记录需要写19周&#xff08;每周2次&#xff09;的观察记录&#xff0c;并根据参考书填写一级、三级、五级的评价指标。 去年中六班的时候&#xff0c;我很认真的手写了21周的户外游戏…