当前位置: 首页 > 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…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...