delphi中堆和栈的区别.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
delphi 堆和栈[转] 2.1 栈 栈是由操作系统在创建线程的时候,系统自动创建,栈是由顶像下分配的,DELPHI中默认的栈大小是1M,这个可以通过Project-Options-Linker-Max Stack size来改变其大小。 栈是线程执行代码的地方,操作系统根据系统调度算法来加载执行的代码,另外栈还存放函数的参数值,局部变量。栈的存取是按4字节偏移,不会根据需要动态增长,因此超出范围会报栈溢出。 2.2 堆 我们把在栈之外的分配内存都叫在堆上分配内存,堆是由程序员分配释放。在DELPHI中是用GetMem.inc中的代码来管理堆的,堆中包含许多大小不确定的块。初始状态下,堆仅有一个块,即堆本身。经过一段时间地取用和回收以后,堆中将可能只剩下一些“切割”后残余的“碎片”,且这些碎片可能已经无法再合并。此时,如果一个新的请求大于任何一个碎片,那么就必须再申请一个新的、大的块放在堆中。堆的使用永远是一个“拆东墙补西墙”的过程。 堆的大小是2G,在扩展内存模式下能达到3G。注意它与数据结构中的堆是两回事,它的分配方式类似于链表,访问“堆”的内容的时候需要先找到这个“堆”,然后再遍历链表,因此“堆”访问会比“栈”慢。 2.3 哪些在栈中 2.3.1 获取栈的首尾地址 获取通常情况下的栈地址 在写汇编的时候,我们知道esp存放栈顶指针,ebp存放栈底指针 procedure GetStackAddress(var AStackTop, AStackBottom: Cardinal); begin asm mov [eax], esp; //栈顶,eax接收第一个参数 mov [edx], ebp; //栈底,edx接收第二个参数 end; end; 获取异常发生时的栈地址 在Windows下,FS:[4]存放发生异常时的栈顶指针。 procedure GetStackAddress(var AStackTop, AStackBottom: Cardinal); begin asm mov ecx, FS:[4]; //FS:[4]放置发生异常时的栈信息 sub ecx, 3; mov [eax], eax; //栈顶,eax接收第一个参数 mov [edx], ebp; //栈低,edx接收第二个参数 end; end; 知道了栈的首尾地址之后,我们就可以取出变量地址,然后和栈的地址比较,如果超出栈的范围,则表示变量在堆中。 2.3.2基本数据类型:函数体中-栈;类中-堆 基本数据类型(Integer、Cardinal、Shortint、Smallint、Longint、Int64、Byte、Word、LongWord、Char)在函数体内分配是在栈中的,如果在类中分配则是在堆中的。另外Int64也是在栈中分配的,它具体的分配是偏移8字节。我们写下如下测试代码: procedure TestInt64; var Value: Int64; StackTop, StackBottom: Cardinal; begin Value := 10; GetStackAddress(StackTop, StackBottom); ShowMessage(Format(StackTop: %s, StackBottom: %s; Int64 Address: %s, [IntToHex(StackTop, 8), IntToHex(StackBottom, 8), IntToHex(Integer(@Value), 8)])); end; 我电脑测试显示的信息为StackTop: 0012F5E0, StackBottom: 0012F628; Int64 Address: 0012F620,从上面信息我们可以看出栈底偏8字节就是Value的地址。 2.3.3 指针类型:指针-栈,指针的内容-堆 指针在函数体内分配,指针的地址是在栈中的,指针的内容是在堆中的。指针如果在类中分配则,指针地址和指针内容都是在堆中的。我们写下如下测试代码: procedure TestPointer; var APoint: Pointer; StackTop, StackBottom: Cardinal; begin GetMem(APoint, 1000); GetStackAddress(StackTop, StackBottom); ShowMessage(Format(StackTop: %s, StackBottom: %s; Pointer Address: %s; Pointer Content Address: %s, [IntToHex(StackT

文档评论(0)

daijun + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档