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

第八十五天学习记录:C++核心:内存分区模型

内存分区模型

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

内存四区的意义:

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

1、程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域
代码区:
存放CPU执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令
全局区:
全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和其他常量也存放在此
该区域的数据在程序结束后由操作系统释放

#include <iostream>
using namespace std;//全局变量
int g_a = 10;
int g_b = 10;int main()
{//创建普通局部变量int a = 10;int b = 10;cout << "局部变量a的地址为:" << &a << endl;cout << "局部变量b的地址为:" << &b << endl;cout << "全局变量a的地址为:" << &g_a << endl;cout << "全局变量b的地址为:" << &g_b << endl;return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;//全局变量
int g_a = 10;
int g_b = 10;//const修饰的全局变量,全局常量
const int c_g_a = 10;
const int c_g_b = 10;int main()
{//全局区//全局变量、静态变量、常量//创建普通局部变量int a = 10;int b = 10;cout << "局部变量a的地址为:" << &a << endl;cout << "局部变量b的地址为:" << &b << endl;cout << "全局变量a的地址为:" << &g_a << endl;cout << "全局变量b的地址为:" << &g_b << endl;//静态变量 在静态变量前面加static,属于静态变量static int s_a = 10;static int s_b = 10;cout << "静态变量a的地址为:" << &s_a << endl;cout << "静态变量b的地址为:" << &s_b << endl;//常量//字符串常量cout << "字符串常量的地址为:" << &"hello world" << endl;//const修饰的变量//const修饰的全局变量,const修饰的局部变量cout << "全局常量a的地址为:" << &c_g_a << endl;cout << "全局常量a的地址为:" << &c_g_b << endl;const int c_l_a = 10;const int c_l_b = 10;cout << "局部常量a的地址为:" << &c_l_a << endl;cout << "局部常量a的地址为:" << &c_l_b << endl;return 0;
}

在这里插入图片描述

2、程序运行后

栈区:

由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。
反面案例:

#include <iostream>
using namespace std;int * func()
{int a = 10;return &a;
}int main()
{int* p = func();cout << *p << endl;//第一次可以打印正确的数字是因为编译器做了保留cout << *p << endl;//第二次这个数据就不再保留的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 << endl;cout << *p << endl;delete p;p = nullptr;return 0;
}

3、new操作符

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

问:C语言中free指针后,指针地址不会变,c++中delete指针后,指针的地址也会改变?
答:在C语言中,调用函数free会释放指针指向的内存,并将内存返回给系统,但指针本身的值不会受到影响,仍然指向之前分配的内存地址。这是因为C语言中的指针只是一个整数变量,它存储的是地址(整数),而不是实际的对象。
而在C++中,delete运算符执行的操作与free函数类似,它会释放指针所指向的内存并将其返回给系统。不同的是,delete还会调用被删除对象的析构函数。此外,当使用delete删除堆上分配的内存后,指向该内存的指针将变为无效指针,指向的内存已经被释放,所以在C++中,删除指针后,指针的值会变成无定义的。不过,可以使用nullptr或0来表示空指针。

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

#include <iostream>
using namespace std;//1、new的基本语法
int * func()
{//在堆区创建整型数据//new返回是该数据类型的指针int* p = new int(10);return p;
}void test01()
{int * p = func();cout << *p << endl;//堆区的数据由程序员管理开辟,程序员管理释放//如果想释放堆区的数据,利用关键字deletedelete p;//cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错
}//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;
}int main()
{test01();test02();return 0;
}

补充:
问:new int[10]后,delete[]为什么可以不在[]加10?
答:
在使用 new 运算符为动态分配内存时,会在堆上额外分配一些元数据来跟踪分配的内存区域的大小。在释放内存时,delete[] 运算符会使用这些元数据来确定应该回收的内存数量,因此你不需要指定数组的大小。

这意味着,如果你使用 new int[10] 分配了一个包含 10 个元素的整数数组,那么在释放数组时,你只需要使用 delete[] 运算符,而不必指定数组大小。

如果你指定了错误的大小,那么会发生未定义的行为。有时候这种错误可能不会导致问题,但有时候会导致程序崩溃或数据损坏。如果你不确定应该使用哪个运算符,最好查阅相关文档或咨询更有经验的开发人员。

问:malloc,free和new,delete的区别。
mallocfree 是在 C 语言中使用的动态内存分配和释放函数,newdelete 是在 C++ 语言中使用的动态内存分配和释放运算符。它们之间的主要区别如下:

  1. mallocfree 是函数,而 newdelete 是运算符。这意味着 newdelete 可以像其他运算符一样重载,而 mallocfree 不能。

  2. newdelete 是 C++ 的内存管理方式,它们可以用于动态分配对象,而 mallocfree 只是简单地分配和释放内存,不能够调用对象的构造函数和析构函数。

  3. newdelete 是类型安全的,它们知道要分配的内存大小,而 mallocfree 可以分配任意大小的内存块。

  4. newdelete 可以跟踪对象的数量和大小,也可以自动调用构造函数和析构函数,而 mallocfree 不能跟踪对象的数量和大小,也不能自动调用构造函数和析构函数。

总之,newdelete 操作符是建议在 C++ 中使用的内存分配和释放方式,它们更加高效、类型安全,并且能够跟踪对象的数量和大小。而 mallocfree 虽然可以在 C++ 中使用,但还是更多的使用在 C 语言和一些使用标准库的编程语言中。

相关文章:

第八十五天学习记录:C++核心:内存分区模型

内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 1、代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理 2、全局区&#xff1a;存放全局变量和静态变量以及常量 3、栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数…...

Chrome远程调试webview

网址 谷歌远程调试解决方案 https://blog.csdn.net/m0_56516186/article/details/131260563Chrome远程调试webview https://blog.csdn.net/weixin_44801980/article/details/117755550...

爬虫与反爬虫的攻防对抗

一、爬虫的简介 1 概念 爬虫最早源于搜索引擎&#xff0c;它是一种按照一定的规则&#xff0c;自动从互联网上抓取信息的程序&#xff0c;又被称为爬虫&#xff0c;网络机器人等。按爬虫功能可以分为网络爬虫和接口爬虫&#xff0c;按授权情况可以分为合法爬虫和恶意爬虫。恶…...

【机器学习】特征工程 - 字典特征提取

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 字典特征提取 一、特征提取API一、提取数字特征二、特征名字三、返回原始数据特征工…...

用户交互----进入游戏

一、增加交互----点击和拖动 1、点击鼠标画点的程序 设置 import pygame # Setup pygame.init() screen pygame.display.set_mode([800,600]) pygame.display.set_caption("单击画圆点") keep_going True RED (255,0,0) …...

排序算法 - 快速排序(4种方法实现)

快速排序 快速排序是啥&#xff1f;三数取中&#xff1a;1.挖坑法&#xff08;推荐掌握&#xff09;2.前后指针法&#xff08;推荐掌握&#xff09;3.左右指针法&#xff08;霍尔版本&#xff09;&#xff08;容易出错&#xff09;4.非递归实现 本篇文章的源代码在这&#xff0…...

C++入门知识点

目录 命名空间 命名空间定义 命名空间使用 法一&#xff1a;加命名空间名称及作用域限定符&#xff1a;&#xff1a; 法二&#xff1a;使用using部分展开&#xff08;授权&#xff09;某个命名空间中的成员 法三&#xff1a;使用using对整个命名空间全部展开&#xff08;授权…...

开眼界了,AI绘画商业化最强玩家是“淘宝商家”

图片来源&#xff1a;由无界AI生成 7月&#xff0c;2023世界人工智能大会在上海召开&#xff0c;顶尖的投资人、创业者都去了。 创业者吐槽&#xff1a;投我啊&#xff0c;我很强。 投资人反问&#xff1a;你的商业模式是什么&#xff1f;护城河是什么&#xff1f; 创业者投资人…...

机器学习与深度学习——自定义函数进行线性回归模型

机器学习与深度学习——自定义函数进行线性回归模型 目的与要求 1、通过自定义函数进行线性回归模型对boston数据集前两个维度的数据进行模型训练并画出SSE和Epoch曲线图&#xff0c;画出真实值和预测值的散点图&#xff0c;最后进行二维和三维度可视化展示数据区域。 2、通过…...

大屏项目也不难

项目环境搭建 使用create-vue初始化项目 npm init vuelatest准备utils模块 业务背景&#xff1a;大屏项目属于后台项目的一个子项目&#xff0c;用户的token是共享的 后台项目 - token - cookie 大屏项目要以同样的方式把token获取到&#xff0c;然后拼接到axios的请求头中…...

c#webclient请求中经常出现的几种异常

WebClient是.NET Framework提供的用于HTTP请求的类&#xff0c;如果在使用WebClient时遇到异常&#xff0c;我们可以根据具体的异常类型进行处理。 以下是一些常见的WebClient异常及其处理方法&#xff1a; System.Net.WebException WebException通常是由于请求超时、网络连…...

设计模式-原型模式

目录 一、传统方式 二、原型模式 三、浅拷贝和深拷贝 克隆羊问题&#xff1a; 现在有一只羊tom&#xff0c;姓名为: tom,年龄为: 1&#xff0c;颜色为: 白色&#xff0c;请编写程序创建和tom羊属性完全相同的10只羊。 一、传统方式 public class Client {public static vo…...

sentinel介绍-分布式微服务流量控制

官网地址 https://sentinelguard.io/ 介绍 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自…...

基于Redisson的Redis结合布隆过滤器使用

一、场景 缓存穿透问题 一般情况下&#xff0c;先查询Redis缓存&#xff0c;如果Redis中没有&#xff0c;再查询MySQL。当某一时刻访问redis的大量key都在redis中不存在时&#xff0c;所有查询都要访问数据库&#xff0c;造成数据库压力顿时上升&#xff0c;这就是缓存穿透。…...

BrowserRouter刷新404解决方案

1、本地开发环境 在js脚本命令里加上 --history-api-fallback "scripts": {"serve": "webpack serve --config webpack.dev.js --history-api-fallback" }2、生产环境&#xff0c;可以修改 nglnx 配置&#xff1a; server {listen XXXX; //端口号…...

解决appium-doctor报opencv4nodejs cannot be found

一、下载cmake 在CMake官网下载&#xff1a;cmake-3.6.1-win64-x64.msi 二、安装cmake cmake安装过程 在安装时要选择勾选为所有用户添加CMake环境变量 三、检查cmake安装 重新管理员打开dos系统cmd命令提示符&#xff0c;输入cmake -version cmake -version四、安装opencv4no…...

安卓通过adb pull和adb push 手机与电脑之间传输文件

1.可以参考这篇文章 https://www.cnblogs.com/hhddcpp/p/4247923.html2.根据上面的文章&#xff0c;我做了如下修改 //设置/system为可读写&#xff1a; adb remount //复制手机中的文件到电脑中。需要在电脑中新建一个文件夹&#xff0c;我新建的文件夹为ce文件夹 adb pull …...

java常用的lambda表达式总结

一、概述 lambda表达式是JDK8中的一个新特性&#xff0c;对某些匿名内部类进行简化&#xff0c;是函数式编程&#xff1b; 二、基本格式 (参数列表)->{方法体代码} 三、Stream流 是jdk8中的新特性&#xff0c;将数据以流的形式进行操作 三、常用方法解析 3.1、准备工作 …...

分布式应用之zookeeper集群+消息队列Kafka

一、zookeeper集群的相关知识 1.zookeeper的概念 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的功能…...

GStreamer学习笔记(四)

Time management 仅当管道处于PLAYING状态时&#xff0c;可以刷新屏幕。如果不在PLAYING状态&#xff0c;什么都不做&#xff0c;因为大多数查询都会失败。 函数与知识点 GstClockTime 说明&#xff1a;所需的超时时间必须以GstClockTime的形式指定。即以纳秒&#xff08;ns…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...