什么事堆栈,堆栈有哪些运算,堆栈怎样存储
发布网友
发布时间:2022-03-28 00:55
我来回答
共1个回答
热心网友
时间:2022-03-28 02:25
stack,其实就是一块内存空间,关键在于他的用途.
1.对于程序指令来说
执行exe时,程序都会默认分配1M堆栈空间,vs2008等开发软件都可以进行调整实际大小.
指令变成一条条机器码,cpu会一条条执行.
例子:
xxxxxxx
call 0x403650 <- --
yyyyy
在执行call命令时,cpu会把下一条指令地址写入堆栈地址空间中,当然也包括其他信息.
0x403650相当于一个子程序的地址,完事后,必然有一个ret之类的指令.这时,cpu根据先前保存的地址,也就是yyyyy这条指令所对应的地址.这样就能继续往下执行了.
关于这一点,用ollydbg好好玩一下,马上就清楚了.
2.一般的应用程序编写.
我们在编写程序时,有时采用堆栈结构,有时采用队列结构,这跟所采用的算法有很大关系.
最常见的递归算法,按递归展开的话,所有的细节就跟第1点完全一样,好处是,大都程序员根本不关心象第1点所描述的细节.只知道其调用过程和最终执行结果.具体细节可能就不关心了.
当把递归算法 用非递归算法写时,很可能你就要引入堆栈结构(其实就是人为手动申请一个内存空间,比如buffer[递归最深层数], 这样,就可以编写出直观的顺序结构的代码. cpu也不用着因调用子程序,一次次把相关信息写入系统的堆栈中(第1点所说)..因为buffer[]的存在就是为了避免这种情况.
--------------------
stack最常用两种操作,push和pop. 你可以用c或是c++ 标准库提供的实现.
如果不是大工程,基本上没必要这么做.
搞个数组 buf[], 再搞个索引变量int index,用来指示top位置. 写入数据时,index++,取出数据时index--
3.最常用的,但易忽略的.
平常所说的,局部变量就是在堆栈中分配的.所以他出了作用域就自动释放了.
c语言很容易理解,不容易出错.
但c++中,编译器有不同的策略.
比如
CTeacher t= bar();
--
CTeacher bar()
{
CTeacher xx;
为CTeacher的成员赋值
return xx.
}
你一定为这里xx对象是局部变量,出了函数作用域,对应的内存主释放了.
CTeacher t= bar();
因为bar()是返回一个Cteacher对象,所以这里就要执行拷贝构造函数,
你会奇怪,问题是bar()返回的对象是无效的.但执行却不会出错.
为什么?
首先对堆栈的理解是对.只是c++编译器内部会改写bar()这个函数.
变成 void bar(CTeacher& tmp)
这样,t就作为引用参数传入了,函数内部创建临时对象,然后赋值给引用对象就成了.结果当然正确了.
4. 是第2点的延伸,相当重要.
一些大的应用工程,往往配合堆来对内存进行管理.
以后你接触一些第三方程序,一定会奇怪,要动态申请内存,直接new或malloc一个对象不就行了么,为什么要这么麻烦.
其中一个重要原因:减少碎片,提高内存使用效率.
你先申请大的空间(new/malloc),然后借助stack的特性来管理和控制这块空间!!!
-------------------------------
ps:理解到这几层差不多够用了