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

Cherno C++ P54 内存:栈与堆

这篇文章我们来谈论一下计算机的内存。在这里,我们着重讨论内存的两个部分:栈与堆。我们需要注意的一点是,这两个概念不是虚拟的,而是在计算机内部真实存在的。它们是我们的CPU当中RAM部分物理上存在的两个区域。我们之所以要重点关注这两个部分,是因为我们在编程的时候,需要把我们的变量储存在这两个区域当中。

首先我们来看一下栈。栈的空间很小,通常只有2M左右,而且这部分是提前定义好了的。堆相对而言,空间更大一些,也是预定义好的,但是堆可以增长。

内存是我们存储数据的地方,而栈与堆给出的内存存储方式则是完全不同的。当然这种区分只是存储方式上的区别,而存储的数据本身是,根本上做的事情是一样的。

比如我们做一个简单的栈分配与堆分配:

int value = 5;        //栈分配
int* hvalue = new int;     //堆分配
*hvalue = 5;

同样的我们也可以做栈/堆分配数组:

int value[5];             //栈分配
int* hvalue = new int[5]; //堆分配

我们可以看到,在堆分配内存的时候,我们需要使用new关键字来进行。

进入到内存中,我们可以看到栈分配和堆分配的不同。首先我们看一下栈分配在内存中是怎样的,我们用如下代码来举例:

int value = 10;             //栈分配
int svalue[5];
svalue[0] = 1;
svalue[1] = 2;
svalue[2] = 3;
svalue[3] = 4;
svalue[4] = 5;

首先我们查找value的位置,如下所示:

然后我们再来查找svalue的位置,其实我们可以从上一张图里面看到,svalue的位置就在value后面不远的地方:

对比一下这两个地址,我们就会发现,它们的距离实际上非常近,这还是因为在debug的模式下,编译器会自动帮我们填充一些safety guard,实际上它们就应该是紧挨着的。我们在栈分配的时候,本质上就是栈顶的指针不停的移动,然后帮我们分配内存,所以栈分配的速度非常快。同样,在栈内存释放的时候,其实也就是指针直接移动回到开头,在CPU当中就是一条指令的事情。

但是如果我们用同样的操作看堆分配的结果,那就是完全不同了,同样的例子:

int* value = new int;             //堆分配
*value = 10;
int* hvalue = new int[5];
hvalue[0] = 1;
hvalue[1] = 2;
hvalue[2] = 3;
hvalue[3] = 4;
hvalue[4] = 5;

然后我们分别查询value和hvalue两个指针指向的位置:

可以明显看到,这两者的位置差的非常远。不论我们使用new还是智能指针,其实都是会使用堆分配,也都会出现这种情况。

new关键字实际上做的事情是调用了malloc函数。在我们程序启动的时候,我们的操作系统会调一部分RAM内存分配过来,当我们使用malloc时,会启动一个叫做free list的东西,来检查内存的空闲状况。这个list会记录目前空闲内存的大小以及该内存起始位置。malloc函数会在其中寻找一块足够大的内存,然后返回指向这块内存的指针,从而实现动态内存分配的效果。

但是malloc是一个非常笨重的函数,因为它需要进行很多记录工作。如果我们要求的内存超出了当前记录的最大内存,那么程序还会向操作系统要求分配更多的内存,而这个过程会更加缓慢。所以堆分配内存有着很高的潜在成本,因为它涉及了一系列的工作。

栈分配是一个CPU指令,而堆分配是一系列工作,这是这两者最大的区别,同时也导致了两者性能上的差别,堆分配的速度会明显更慢。而且堆分配还会产生cache misses,在数量很多(可能以百万计)的时候,也会带来问题。

所以我们在分配内存的时候,应该优先在栈上分配内存,除非我们需要很大一部分内存。这个是非常真实的性能区别,但是访问栈内存和堆内存倒是没有什么明显区别。

以上就是本篇文章的全部内容了,希望大家喜欢!

相关文章:

Cherno C++ P54 内存:栈与堆

这篇文章我们来谈论一下计算机的内存。在这里,我们着重讨论内存的两个部分:栈与堆。我们需要注意的一点是,这两个概念不是虚拟的,而是在计算机内部真实存在的。它们是我们的CPU当中RAM部分物理上存在的两个区域。我们之所以要重点…...

对项目交接的一些思考

天下大势,分久必合合久必分。这些年交接了很多项目,也从别人那里接手了很多项目。最近又接收了一些项目,但团队接收的效果不是很好,或者说掌握的不全面,所以就在想怎么能够做的更好一些? 团队关系 其实我…...

【PYTORCH】官方的turoria实现中英文翻译

参考 https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html 背景 pytorch官方的是seq2seq是法语到英文,做了一个中文到英文的。 数据集 下载后解压,使用的data\testsets\devset\UNv1.0.devset.zh和UNv1.0.devset.en&#x…...

【算法与数据结构】并查集详解+题目

目录 一,什么是并查集 二,并查集的结构 三,并查集的代码实现 1,并查集的大致结构和初始化 2,find操作 3,Union操作 4,优化 小结: 四,并查集的应用场景 省份…...

【动态路由】系统web url整合系列【springcloud-gateway实现】【不改hosts文件版】组件一:多个Eureka路由过滤器

需求 实现URL web资源整合,实现使用一个web地址访问多个web资源 方案 本方案使用SpringCloud Gateway实现,不需要在hosts文件加添加域名映射(也不需要定义一系列域名),通过url路径来将请求转发到不同的Web资源 如&…...

Mybatis-扩展功能

逻辑删除乐观锁 MyBatisPlus从入门到精通-3(含mp代码生成器) Db静态工具类 Spring依赖循环问题 代码生成器 MybatisPlus代码生成器 枚举处理器 我们这里用int来存储状态 需要注解,很不灵活 希望用枚举类来代替这个Integer 这样的话我…...

基于SpringBoot实现的大学社团平台系统实现功能六

一、前言介绍: 1.1 项目摘要 随着高校社团活动的日益丰富和多样化,学生对于社团管理和参与的需求也在不断增加。传统的社团管理方式往往存在效率低下、信息不透明等问题,无法满足现代学生对于便捷、高效社团管理的需求。因此,利…...

电子电气架构 --- 机器学习推动车载雷达的发展

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…...

python从入门到进去

python从入门到进去 第一章、软件和工具的安装一、安装 python 解释器二、安装 pycharm 第二章、初识 python一、注释可分三种二、打印输入语句三、变量1、基本数据类型1.1、整数数据类型 int1.2、浮点数数据类型 float1.3、布尔数据类型 boolean1.4、字符串数据类型 string 2、…...

智能化客户画像构建管理:AI视频监控在大型商场的技术

前言:某商家为了优化卖场服务与营销策略,希望通过非侵入式手段获取客户画像,不仅可以帮助卖场提升服务质量、优化营销策略,还能通过数据驱动的方式提升销售业绩和顾客满意度,为卖场的长期发展奠定坚实的基础。 具体需求…...

php 拼接字符串

php 拼接字符串 .连字符"Hello, $name" 双引号内会解析变量"Hello, {$name}Doe" 使用花括号可以更明确标识变量名sprintf("Hello, %s", $name) 使用sprintfheredoc语法&#xff0c;同样支持变量的解析$html <<<EOT <p>Hello, $…...

Deepseek实用万能提问模板

一&#xff0c;背景需求约束条件 背景:提供与问题相关的时间、地点、人物、事件等信息&#xff0c;帮助 DeepSeek 更好地理解问题的情境。 需求:清晰明确地阐述你希望 DeepSeek完成的任务或提供的信息。 约束条件:可根据具体情况&#xff0c;对回答的范围、格式、字数等进行…...

MySQL、MariaDB 和 TDSQL 的区别

MySQL、MariaDB 和 TDSQL 是三种不同的数据库管理系统&#xff0c;它们在设计理念、功能、性能和使用场景上有一些显著的区别。 以下是对这三者的详细比较和介绍。 1. MySQL 概述 类型&#xff1a;关系型数据库管理系统&#xff08;RDBMS&#xff09;。开发者&#xff1a;最…...

Android车机DIY开发之软件篇(十七) Android模拟器移植Automotive

AndroidProducts.mk 路径&#xff1a; /device/generic/goldfish/pc/AndroidProducts.mk sdk_pc_x86_64.mk路径&#xff1a; /device/generic/goldfish/pc/sdk_pc_x86_64.mk sdk_car_x86_64.mk路径&#xff1a; /device/generic/goldfish/car/sdk_car_x86_64.mk BoardConfig.mk…...

[Unity角色控制专题] (借助ai)详细解析官方第三人称控制器

首先模板链接在这里&#xff0c;你可以直接下载并导入unity即可查看官方为开发者写好一套控制器 本文的ai工具用到了豆包&#xff0c;其灵活程度很高&#xff0c;总结能力也强过我太多 因此大量使用&#xff0c;不喜勿喷 Starter Assets - ThirdPerson | Updates in new Charac…...

【数据结构基础_链表】

1、链表的定义 链表与数组的区分&#xff1a; 数组是一块连续的内存空间&#xff0c;有了这块内存空间的首地址&#xff0c;就能直接通过索引计算出任意位置的元素地址。 数组最大的优势是支持通过索引快速访问元素&#xff0c;而链表就不支持。链表不一样&#xff0c;一条链…...

Java 实现 Redis中的GEO数据结构

Java 实现 Redis中的GEO数据结构 LBS &#xff08;基于位置信息服务&#xff08;Location-Based Service&#xff0c;LBS&#xff09;&#xff09;应用访问的数据是和人 或物关联的一组经纬度信息&#xff0c;而且要能查询相邻的经纬度范围&#xff0c;GEO 就非常适合应用在 …...

PostgreSQL如何关闭自动commit

PostgreSQL如何关闭自动commit 在 PostgreSQL 中&#xff0c;默认情况下&#xff0c;每个 SQL 语句都会自动提交&#xff08;即 AUTOCOMMIT 是开启的&#xff09;。如果希望关闭自动提交&#xff0c;以便手动控制事务的提交和回滚&#xff0c;可以通过以下方法实现。 1 使用 …...

1、云原生写在前面

云原生技术是什么&#xff08;包含哪些组件&#xff09;&#xff1f;每个组件是负责什么&#xff1f;学习这些组件技术能解决什问题&#xff1f;哪些类企业需要用到&#xff1f; 这是标准系列的问题&#xff0c;通过 deepseek 的深度思考就能得到我们想要的易于理解的人话式的…...

Redis离线安装

Linux系统Centos安装部署Redis缓存插件 参考&#xff1a;Redis中文网&#xff1a; https://www.redis.net.cn/ 参考&#xff1a;RPM软件包下载地址&#xff1a; https://rpmfind.net/linux/RPM/index.html http://rpm.pbone.net/ https://mirrors.aliyun.com/centos/7/os…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...