堆和栈的区别(经典)

堆与栈的区别(经典讲解) k最近邻算法(k-Nearest Neighbor,KNN )Python实现一、预备知识—程序 的内存分配二、例子程序三、堆和栈的理论知识1 申请方式2 申请后系统的响应3 申请大小的限制4 申请效率的比较:5 堆和栈中的存储内容6 存取效率的比较7 小结 摘要: 对于堆和栈,很多朋友都是不怎么理解的,就算是开发了程序多年的朋友都会容易混淆。其实要区分它们并不难,但是怎样使自己永久不会忘记哪得有... 阅读详情

堆和栈的区别(转贴,原作者姓名不详)

0、预备知识—程序的内存分配
一个由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—> 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—> 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—>全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束后由系统释放
4、文字常量区—>常量字符串就是放在这里的。程序结束后由系统释放
5、程序代码区—>存放函数体的二进制代码。

一、例子程序
这是一个前辈写的,非常详细
//main.cpp 
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main() 
{ 
    int b; //栈
    char s[] = "abc"; //栈
    char *p2; //栈
    char *p3 = "123456"; //123456\0在常量区,p3在栈上。
    static int c =0; //全局(静态)初始化区
    p1 = (char *)malloc(10); 
    p2 = (char *)malloc(20); //分配得来的和字节的区域就在堆区。
    strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}  


二、堆和栈的理论知识

2.1申请方式 
stack: 
由系统自动分配。例如,声明在函数中一个局部变量int b; 系统自动在栈中为b开辟空间
heap: 
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10); 
在C++中用new运算符
如p2 = (char *)malloc(10); 
但是注意p1、p2本身是在栈中的。

2.2 申请后系统的响应

栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程
序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制 
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便. 另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

2.5堆和栈中的存储内容 

栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

2.6存取效率的比较 
char s1[] = "aaaaaaaaaaaaaaa"; 
char *s2 = "bbbbbbbbbbbbbbbbb"; 
aaaaaaaaaaa是在运行时刻赋值的;而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main() 
{ 
    char a = 1; 
    char c[] = "1234567890"; 
    char *p ="1234567890"; 
    a = c[1]; 
    a = p[1]; 
    return;
}

对应的汇编代码
10: a = c[1]; 
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 
0040106A 88 4D FC mov byte ptr [ebp-4],cl 
11: a = p[1]; 
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 
00401070 8A 42 01 mov al,byte ptr [edx+1] 
00401073 88 45 FC mov byte ptr [ebp-4],al 

第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。

2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作
和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
(生气)

Word毕业论文排版:图片和表格题注的终极指南(含自动编号技巧) 本文是Word毕业论文排版中图片和表格题注的终极指南,详细讲解了如何利用题注功能实现自动编号,告别繁琐易错的手动操作。核心内容包括创建定制标签、配置带章节的编号格式、插入交叉引用以及一键更新全文编号的技巧,旨在帮助学生构建自动化文档体系,提升排版效率和论文严谨性。 阅读详情

相关推荐

手把手教你用RMII接口配置以太网PHY芯片(附YT8512实战代码)

本文详细介绍了如何使用RMII接口配置以太网PHY芯片,以国产YT8512为例,提供从硬件设计到软件驱动的全流程实战指南。内容包括RMII接口技术解析、YT8512硬件设计要点、驱动开发实战代码及常见问题排查,帮助开发者快速实现以太网通信功能。

mac99的博客 996

栈帧相关知识总结

    在学习栈帧相关知识前,我们需要明确一些知识点,那就是在电脑中我们的地址空间是以什么样的方式存在的,在这里我们可以用一张图片表示:栈和堆的存储方式:栈(stack)的存储方式是自上而下的,先入后出的方式。生长方式往下生长堆(heap)的存储方式是自下而上的,先入先出的方式,生长方式往上生长在观察完如图所示的图片之后,我们在开始栈帧的研究操作之前,我们先来明确一些基本的概念:我们知道每一次函数...

sd116460的博客 512

PyTorch+C3D实战:用UCF101数据集训练你的第一个视频动作识别模型(附完整代码)

本文详细介绍了如何使用PyTorch和C3D模型在UCF101数据集上构建视频动作识别系统。从环境配置、数据预处理到模型训练与优化,提供了完整的代码实战指南,帮助开发者快速掌握视频行为识别技术。文章特别强调了3D卷积核设计、混合精度训练等关键技术要点,并分享了模型部署优化经验。

weixin_29233857的博客 218

Pull和Push的区别

  Pull Push 实时性 取决于定时 较好 客户端状态 有状态,需要知道拉取点 无状态 服务端状态 无状态 有状态,需要了解每个客户端的推送点 通常实现 短连接 长连接 难点 实时性和流量的取舍 客户端能力和push能力不匹配问题 ...

无怨无悔专栏 8016

gesp c++ 五级知识点

gesp c++ 五级知识点

MMD.然大大 2009

Win10系统蓝屏错误BAD SYSTEM CONFIG INFO的解决方案

BAD SYSTEM CONFIG INFO错误是Win10系统中较为常见的一种蓝屏错误,通常与系统配置文件损坏或丢失有关。本文介绍了三种有效的解决方法:使用系统修复高级选项修复、通过PE修复文件和重装新系统。用户可以根据实际情况选择合适的方法进行操作。同时,建议用户定期备份系统重要文件和数据,以防止类似问题的发生。在遇到问题时,保持冷静并耐心操作,通常可以顺利解决问题。

mmoo_python的博客 7724

数据结构——栈(Stack)与队列(Queue)的手写实例

文章目录一、 栈与队列的定义二、 用数组实现栈1、栈的接口定义2、栈的接口实现3、栈的测试三、 用数组实现队列1、队列的接口定义2、队列的接口实现3、队列的测试 一、 栈与队列的定义 栈[Stack]:是一种限定仅在表尾进行插入和删除操作的线性表;即后进先出(LIFO-last in first out),最后插入的元素最先出来。  队列[Queue]:是一种限定仅在表头进行删除操作,仅在...

我的博客 934

【Unity Shader】2D模型 3D模型混用的穿模问题(Spine在3D场景中出现前后穿模问题的解决办法)

问题描述: 在3D场景中使用Spine模型(2D), 因为Spine需要像Billboard类似的处理,永远是垂直与相机的, 所以一般情况下2D模型能正常显示且前后的阻挡关系也是没有问题的,如下图所示,一切都很美好.(这里用一个四边形,图中的福字表示2D模型) 可是如果后面蓝色的格子比较高,或者2D角色本身也比较高,那么就会出现模型穿插的问题,如下图所示: 如果吧2D模型竖立起来,前后关系肯定是没有问题的,所以也能避免模型穿插的问题,可是就没有Billboard效果,圆形的福字已经被压扁了,如下图:

Vitens的专栏 4591

栈_数组模拟栈_实现简单计算器

package com.zsx.structure.stack; class Stack { //大小 private int maxSize; //数据 private T[] stack; //栈顶 private int top = -1; public Stack(int maxSize) { this.maxSize = maxSize; stack = (T[]) new Object[maxSize]; } /** * 判断满 * * @return */ publ

IT_Java_Roy的博客 201

STM32F407与AD7766实战:如何用SPI+DMA实现高速ADC数据采集(附完整代码)

本文详细介绍了如何利用STM32F407的SPI接口与DMA控制器,高效稳定地驱动24位高精度ADC芯片AD7766,实现高速连续数据采集。通过对比传统中断方式的瓶颈,阐述了SPI+DMA方案如何大幅降低CPU负载,并提供了从硬件设计、CubeMX配置到核心驱动代码的完整实战指南,帮助工程师解决高速ADC数据采集中的性能难题。

weixin_29281941的博客 188

YOLO26 标签分配机制:STAL 小目标感知分配策略

YOLO26提出的STAL标签分配策略通过尺度感知机制优化了小目标检测性能。该方法根据目标面积将检测对象分为小、中、大三类,分别采用差异化的分配参数(TopK数量、IoU阈值和中心度权重),特别是对小目标采用更宽松的匹配条件和更高的中心度权重。实验结果表明,STAL策略显著提升了小目标检测精度(AP_small),同时保持了整体检测性能(mAP),为解决目标检测中尺度不平衡问题提供了有效方案。

一键难忘的博客 789

push和pull方式对比-消息中间件(二)

push方式 消息保存在服务端。容易造成消息堆积。 服务端需要维护每次传输状态,遇到问题需要重试 非常实时 服务端需要依据订阅者消费能力做流控(流转机制) pull方式 保存在消费端。获取消息方便。 传输失败,不需要重试 默认的端短询方式的实时性依赖于pull间隔时间,间隔越大,实时性越低,长轮询方式和push一致 消费端可以根据自身消费能力决定是否pull(流转机制) ...

Hyperin 3746

智启古文字新章:AI、ML与大数据驱动的知识图谱构建

摘要:本文聚焦AI、ML与大数据驱动的古文字知识图谱构建。开篇点明古文字研究困境,凸显技术革新迫切性。随后阐释AI、ML、大数据基础概念,详解其在图谱构建里的数据采集、知识抽取、关系挖掘运作流程,穿插线性代数、概率论等数学原理。实战展示殷商甲骨文图谱搭建全程,含数据处理、模型训练。还探讨跨模态融合等前沿挑战应对,兼述技术融合衍生的教育科普革新、伦理文化责任、国际合作交流,勾勒古文字数字永生的长远愿景。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1615

java堆和栈的区别_Java堆和栈的区别 经典总结

栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时...

weixin_35960434的博客 158

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

堆 和 栈的 区别(经典)——一篇理解堆和栈区别的好文章

堆和栈的区别  一、预备知识—程序的内存分配  一个由C/C++编译的程序占用的内存分为以下几个部分  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其  操作方式类似于数据结构中的栈。  2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回  收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵

kernaly的专栏 755

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

堆和栈的区别(非常经典的文章)

一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回 收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(s

Max_Fu的专栏 385

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

堆 和 栈的 区别(经典)

堆 和 栈的 区别(经典) 转载一篇理解堆和栈区别的好文章 此文章虽然是面向C/C++程序员写得,但是对咱们Java程序员还是很有帮助的。  堆和栈的区别  一、预备知识—程序的内存分配  一个由C/C++编译的程序占用的内存分为以下几个部分  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其  操作方式类似于数据结构中的栈。

Wilsonboliu的专栏 493

UC3842/UC3843 PWM时序图与内部逻辑门电路深度解析

开关电源设计中,PWM(脉宽调制)是核心控制手段,理解PWM时序图是排查电源故障的基础。基于逻辑门电路的硬件控制环具备纳秒级响应速度和确定性,比依赖微控制器中断更可靠,特别适合逐周期限流保护场景。峰值电流模式通过比较电流采样与误差放大器输出来决定占空比,配合RS触发器、振荡器等逻辑单元,构成完整的电源控制引擎。UC3842/UC3843作为经典电流模式PWM控制器,内部集成误差放大器、比较器、RS触发器等硬件逻辑,广泛用于反激、正激及Buck电路。掌握其时序图和逻辑门工作原理,可有效解决占空比抖动、过流打嗝

weixin_34274029的博客 1027

堆和栈的区别(经典版)

这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。

关注我!带你一路 "狂飙" 到底! 1442

堆和栈的区别——经典解释

非本人作也!因非常经典,所以收归旗下,与众人阅之!原作者不祥! 堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据

1097

别再问我堆和栈了!堆和栈的区别(经典篇总结)

一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。 3、全局区(静态区)(stati...

chen801090的博客 214

(经典)堆和栈的区别

一、预备知识—程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其 操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS 回收。注意它与数据结构中的堆是两回事,分配方式倒是类似...

weixin_30710457的博客 68
上一篇: opencv2学习笔记5-操作图像(掩模拷贝ROI-不一样大小的图像相加)
下一篇: string::npos的一些说明
devil_pull
博客等级 码龄15年 12粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值