数据在内存中是如何存储的

数据在内存中的存储 文章详解加练习题(理论加实践) 希望给位有所收获 阅读详情


在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多) 明确区分堆与栈在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。

堆与栈

首先,我们举一个例子:

1 void f() {
2   int* p=new int[5];
3   }

这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中。

他在VC6下的汇编代码如下:

1 00401028
2 push 14h 0040102A
3 call operator
4 new (00401060) 0040102F
5 add esp,4 00401032
6 mov dword ptr [ebp-8],eax 00401035
7 mov eax,dword ptr [ebp-8] 00401038
8 mov dword ptr [ebp-4],eax

这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。

好了,我们回到我们的主题:堆和栈究竟有什么区别?

主要的区别由以下几点:

  1. 管理方式不同;
  2. 空间大小不同;
  3. 能否产生碎片不同;
  4. 生长方向不同;
  5. 分配方式不同;
  6. 分配效率不同;
管理方式

管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。

空间大小

空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改: 打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。 注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。

碎片问题

碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。

生长方向

生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。

分配方式

分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。

分配效率

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。 虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。

无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的:) 对了,还有一件事,如果有人把堆栈合起来说,那它的意思是栈,可不是堆。

带有数据存储内存块的数据存储 然后,如果数据表中显示的数据存储读取或数据存储写入块引用由信号对象定义的数据存储,则该表包括与该对象对应的行。您可以在数据存储读取和数据存储写入块中使用此名称,就像它是数据存储内存块的数据存储名称一样。对于本地数据存储,对于下面列出的每个参数,您可以显式设置值,也可以让数据存储从数据存储写入和数据存储读取块继承值。数据存储名称属性指定数据存储写入和数据存储读取阻止访问的数据存储的名称。要定义仅在特定子系统及其包含的子系统中可见,但在模型块中不可见的数据存储,请将数据存储内存块拖动到子系统中。 阅读详情

相关推荐

PDMS二次开发入门:手把手教你用PML2写第一个交互式窗体工具

本文详细介绍了如何使用PML2进行AVEVA PDMS二次开发,从零开始构建交互式窗体工具。通过PML2语言的面向对象特性、即时调试能力和深度系统集成优势,开发者可以高效创建自动化设计工具、批量修改属性和定制报表系统。文章包含开发环境配置、基础语法、窗体架构设计、事件处理等实战内容,帮助读者快速掌握PDMS二次开发技能。

weixin_29281941的博客 271

数据在内存中的存储:详细解析

数据类型详细介绍整型在内存中的存储:原码、反码、补码大小端字节序介绍及判断浮点型在内存中的存储解析计算机中有多种数据类型,包括整型、浮点型、字符型等,每种数据类型都有其特定的表示范围和存储方式。

StandDev的博客 465

CarSim转向控制对比指南:开环扭矩控制vs转角控制(附Simulink连接示例)

本文深入对比了CarSim中车轮转角控制与开环扭矩控制的核心原理与适用场景。开环扭矩控制能激活完整的转向系统动力学,更适用于EPS控制策略开发与驾驶员在环仿真等对真实性要求高的场景。文章提供了详细的Simulink接口配置步骤与连接示例,为车辆动力学仿真工程师提供了清晰的决策与实操指南。

weixin_29199873的博客 478

多字节数据在内存(或显存)和寄存器上存放顺序

多字节数据在内存、显存(N卡)和寄存器(N卡)上的存放顺序。   char4 dog; dog.x ...   第1个字节 dog.y .... 第2个字节 dog.z ..... 第3个字节 doz.w ...... 第4个字节 ?

打不死的心态活到老 4616

同花顺Supermind量化交易 技术面分析专题(一)-- 相似k线的形态验证与选股

W底”,“多头上涨”,“趋势回踩”,”上涨中继“这些都是常见的K线形态,以”上涨中继“为例,当股价快速上涨后,出现盘整形态而非顶部形态,预示股价还会进一步上涨,那么本节主要讲述”上涨中继”形态是否能够预测未来股价上涨,以及如何应用“上涨中继”形态,来快速选股。"相似K线"技术相比于传统的K线组合而言更具技术性,其还有较多的运用空间,比如:运用顶部形态来监控个股潜在的下跌风险,运用相似度来监控个股是否脱离大盘走势,研究各类形态的上涨预测能力,并应用于选股等等。第一步:选取一段标准的“上涨中继”形态K线图。

qq_22808537的博客 4544

华为昇腾 Atlas 200I DK A2 开发板编程接口学习入门:系统安装和开发步骤、注意事项与典型案例实战

华为昇腾开发板编程接口指南:从入门到进阶 本文系统介绍了华为昇腾开发板的编程接口体系,涵盖MindXSDK和AscendCL两大核心框架。MindXSDK提供高层封装接口,适合快速搭建视觉应用;AscendCL则是底层接口,需手动管理设备内存。文章详细讲解了: 开发环境搭建步骤,包括系统配置、依赖安装 MindXSDK组件化编程流程(图像分类实例) AscendCL底层开发方法(内存管理、模型推理) 常见问题解决方案和调试技巧 两个典型应用实例(摄像头目标检测和图像分类) 针对小白开发者,推荐从MindXS

bother3000的博客 2424

数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)

数据在内存中的存储(了解数据在内存中的存储规则,看这一篇就够了!)

秋刀鱼不做梦的编程日常 1497

ARKit面部动画实战:如何用blend shape让数字人表情更自然(附中文对照表)

本文深入探讨了如何利用ARKit的blend shape技术驱动数字人面部动画,以实现更自然生动的表情。文章提供了详细的blend shape中文对照表,并分享了实战技巧,包括构建复合表情动画序列、处理不对称性与微表情,以及性能优化策略,旨在帮助开发者高效提升数字人的表情表现力。

weixin_29292535的博客 325

C语言-数据在内存中的存储

数据在内存中的存储

2201_76032321的博客 920

Creo报错代码-9?手把手教你重新生成许可证文件(基于Creo 10.0)

本文详细解析Creo报错代码-9的成因及解决方案,重点介绍如何重新生成许可证文件以应对网络环境变化导致的验证失败。通过分步指南和高级技巧,帮助用户有效管理多网络环境下的Creo许可证问题,提升工作效率。

weixin_30839881的博客 558

用 CL_HTTP_CLIENT 正确处理 Cookie,彻底解决 SAP Gateway OData 的 CSRF Token 校验失败

SAP OData 集成中 CSRF Token 校验失败的解决方案 问题现象:使用 Postman 测试 OData 写入成功,但 ABAP 代码调用时出现 CSRF token validation failed 错误。 根本原因:Postman 自动处理 Cookie,而 ABAP 代码仅获取了 CSRF Token 却遗漏了 Cookie 信息。SAP Gateway 要求修改请求必须同时携带 Token 和 Cookie 才能通过校验。 解决方案: 通过 GET 请求同时获取 CSRF Token

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 431

数据在内存中的储存

数据的存储

weixin_73580647的博客 745

【WRF安装(2025)】服务器移植 WRF 安装环境

【WRF安装(2025)】服务器移植 WRF 安装环境

WW、forever的博客 106

【C语言】数据在内存中的存储

各位小伙伴大家好!上期小编给大家讲解了C语言中的字符函数、字符串函数,内存函数,接下来我们讲解一下数据在内存中的存储!在C语言中,数据在内存中的存储方式受到数据类型、对齐规则和编译器实现的影响。数据类型大小:C语言中的基本数据类型(如intcharfloatdouble等)在内存中占用的字节数是由编译器和目标系统架构决定的。例如,在32位系统中,int通常占用4个字节,float占用4个字节,而double占用8个字节。内存对齐:为了提高内存访问效率,C语言在存储数据时通常会遵循特定的对齐规则。

Guiat的博客 2271

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

你知道数据在内存中是如何存储的嘛?

本篇详细介绍了整型、浮点型数据在内存中的存储方式

春人.的博客 2666

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

数据是如何在内存中存储的?

数据的类型 一些常见的数据类型 char 字符数据类型 short 短整型 int 整形 long 长整型 long long 更长的整形 float 单精度浮点数 double 双精度浮点数 通过前面的学习,大家对以上的类型已经有一定了解了。 每次谈到数据类型,就不得不问到一个经典的问题:C语言有没有字符串类型? 答案是没有。但C语言有数组,可以通过定义字符数组,把字符串存在字符数组里。

qq_52363432的博客 4700

你知道数据是怎么在内存中存储的吗?

我们经常会用到整型数据跟浮点型数据,怎么用相信大家都很明白,那么他们在内存中是怎么存储的你知道吗?

qq_53539886的博客 1406
上一篇: 内网与外网通讯 socket
下一篇: MTU原理及相关问题分析
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值