作为一个新手,作者对堆和栈的概念总是很模糊。他们认识我,但我只是偶尔见面而没有深厚的友谊。
但是,在计算机领域,堆栈是一个不容忽视的概念,并且堆栈是两个数据结构。堆栈是一种数据结构,其中数据项按顺序排列,并且数据项只能在一端(称为堆栈的顶部)插入和删除。在微控制器应用中,堆栈是一个特殊的存储区,其主要功能是临时存储数据和地址,通常用于保护断点和现场。关键点:堆,先入队列,先进先出(FIFO-先入先出)。堆栈,先进先出(FILO-先进/后出)。
在通常情况下,如果有人将堆栈放在一起,则表示堆栈而不是堆。 。 。 。
它们之间的差异始终使初学者感到困惑。作者本人是,所以我认为有必要对它进行一点整理,至少我心中有一个概念。能力问题,写得不好,对于这个问题,所有的IT BBS和博客都写得很好,每个人都可以学习。百度百科中堆与栈的比较分析:
堆栈空间分配
堆栈(操作系统):由操作系统自动分配和释放,存储函数参数值,局部变量值等。其操作类似于数据结构中的堆栈。
堆(操作系统):通常由程序员分配和释放,如果程序员不释放,则OS可能会在程序结束时对其进行回收。分配方法类似于链表。
堆栈缓存方法
堆栈使用第一级缓存。它们通常在被调用时位于存储空间中,并在调用后立即释放。
堆存储在第二级缓存中,生命周期由虚拟机的垃圾收集算法确定(不是一旦成为孤儿就可以回收)。因此,调用这些对象的速度相对较低。
堆栈数据结构的差异
堆(数据结构):堆可以看作是一棵树,例如:堆排序。
堆栈(数据结构):先进先出的数据结构。
例如:顺序堆栈AStack的类定义
模板
AStack类{

私人:
int大小; //数组的大小
T * stackArray; //用于存储堆栈元素的数组
int top; //数组元素在堆栈顶部的索引
公开
:
AStack(int MaxStackSize)//构造函数
{size = MaxStackSize; stackArray = new T [MaxStackSize];顶部= -1; }
〜AStack(){删除[] stackArray;} //析构函数
bool Push(常量T&项目); //将元素推到堆栈顶部
布尔流行乐(T&item); //从堆栈顶部弹出一个元素
bool Peek(T&item)常量; //访问堆栈的顶部元素
int IsEmpty(void)const {返回顶部= = -1; }
//检查堆栈是否为空
int IsFull(void)const {返回topsize-1; }

//检查堆栈是否已满
void clear(void){top-1;} //清除堆栈
};
首先,让我们举个例子:
voidf(){int * p = newint [5];}
这个简短的句子包括堆和栈。当我们看到新的东西时,我们首先应该认为我们已经分配了一块堆内存。指针p呢?他分配了一块堆栈内存,因此这句话的意思是:指向堆栈内存块的指针p存储在堆栈内存中。程序将首先确定在堆中分配的内存大小,然后调用operatornew分配内存,然后返回该内存的第一个地址并将其放在堆栈上。他在VC6下的汇编代码如下:
00401028push14h
0040102Acalloperatornew(0040106 0)
0040102Faddesp,4
00401032movdwordptr [ebp-8],eax
00401035moveax,dwordptr [ebp-8]
00401038movdwordptr [ebp-4],eax
在这里,为了简单起见,我们没有释放内存,那么我们如何释放它呢?是删除吗? O,错了,应该是delete [] p,这是告诉编译器:我删除了一个数组,VC6将根据相应的cookie信息释放内存。
好的,让我们回到我们的主题:堆和栈有什么区别?作者对此做出了谦逊的结论
主要区别如下:

1、不同的管理方法;
2、空间大小不同;
3、能否产生片段不同;
4、不同的生长方向;
5、不同的分配方法;
6、不同的分配效率;
管理方法:对于堆栈,它是由编译器自动管理的,无需我们手动控制;对于堆,释放由程序员控制,很容易产生内存泄漏。
空间大小:通常,在32位系统中,堆内存可以达到4G空间。从这个角度来看,堆内存几乎是无限的。但是对于堆栈,通常有一定大小的空间。例如,在VC6下,默认堆栈空间大小为1M(似乎是,我记不清楚了)。当然,我们可以修改:
打开项目并按如下所示操作菜单:Project-> Setting-> Link,在Category中选择Output,然后设置最大堆栈大小并提交Reserve。
注:保留的最小值为4Byte;提交保留在虚拟内存的页面文件中。较大的设置将为堆栈打开较大的值,这可能会增加内存开销和启动时间。
碎片问题:对于堆,频繁的new / delete不可避免地会导致内存空间的不连续性,从而导致大量的碎片并降低程序效率。对于堆栈,此问题不存在,因为堆栈是先进先出队列,所以它们是的对应关系,因此永远不会有从堆栈中间弹出的内存块,在弹出之前,在上面的后退堆栈的内容已弹出。有关详细信息,请参阅数据结构。我们在这里不会一一讨论。
增长方向:对于堆来说,增长方向是向上的,即内存地址增加的方向;对于堆栈,其增长方向是向下的,即内存地址减少的方向。
分配方法:堆是动态分配的,并且没有静态分配的堆。堆栈有两种分配方法:静态分配和动态分配。静态分配由编译器完成,例如局部变量的分配。动态分配是由alloca函数分配的,但是堆栈的动态分配与堆不同。他的动态分配由编译器释放,不需要我们手动实现。
分配效率:堆栈是机器系统提供的数据结构,计算机将在底部为堆栈提供支持:分配特殊的寄存器来存储堆栈的地址,而push和pop具有特殊的指令来执行,这决定了堆栈的效率比较高。堆由C / C ++函数库提供。其机制非常复杂。例如,为了分配一块内存,库函数将根据某种算法搜索堆内存的可用性(有关特定算法,请参阅数据结构/操作系统)。如果没有足够的空间(也许(由于过多的内存碎片),可以调用系统函数来增加程序数据段的存储空间,从而有机会分配足够的内存,然后继续返回。显然,堆的效率要比堆的效率低得多。
从这里,我们可以看到,与堆栈相比,由于使用了大量的new / delete,堆可能会导致很多内存碎片;因为没有特殊的系统支持,所以效率很低;因为它可能导致用户模式和核心模式,所以切换和存储应用程序的成本变得更加昂贵。因此,堆栈是程序中使用最广泛的。甚至函数调用也用于完成堆栈。函数调用过程中的参数,返回地址,EBP和局部变量都存储在堆栈中。因此,我们建议所有人都尝试使用堆栈而不是堆。
尽管堆栈具有很多好处,因为与堆相比,它不那么灵活,但有时最好使用堆来分配大量内存空间。
无论是堆还是堆栈,都必须防止发生跨边界现象(除非您有意使之成为跨边界的),因为跨边界的结果是程序崩溃或破坏程序的堆和堆栈结构,导致意外结果,即使在程序运行过程中没有发生上述问题,您仍然必须要小心,也许随时会崩溃,那么调试就很困难了:)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-358174-1.html
有一种霉变的味道
醒醒酒吧
有道理