我估摸着内存分配+释放是个基础函数,有些人可能没注意此类函数或细究,但我觉得还是弄明白的好。

介绍下面内存函数前,先说一下MM的一些过程,如不关心可忽略:

TMemoryManager = recordGetMem: function(Size: Integer): Pointer;FreeMem: function(P: Pointer): Integer;ReallocMem: function(P: Pointer; Size: Integer): Pointer;
end;varMemoryManager: TMemoryManager = (GetMem: SysGetMem;FreeMem: SysFreeMem;ReallocMem: SysReallocMem);

以上是D7版本的MM函数,其中变量MemoryManager我称为MM函数,请注意。

D2005-D2007以上版本(不确认哪个版本),MM函数多了AllocMem及RegisterLeak/UnRegisterLeak函数,与本文无关,就不多说了。

第三方MM接管的就是这MM的几个函数,达到外挂目地,而Sys打头的SysGetMem, SysFreeMem, SysReallocMem则为本身系统自带的MM处理。

一:New/Dispose

此两函数,估计学delphi/pascal,就知道:为record/object此类数据进行分配和释放内存块

然后分配与释放是调用的是GetMem/FreeMem函数,与GetMem/FreeMem不同之处是:

New()在GetMem后,进行了initialize(x)操作,即对record/object的数据进行初始化的操作.

initialize函数,在system单元,该函数说白了,即对record/object里面中,含有string,interface, dync array,variant,record,array的字段,进行初始化为0(清空).

这一步很重要,因为GetMem返回的内存块可能重复使用过的,使用过的,表示有值。

有值的情况下,再重新赋值,就表示旧地址对应的数据要先清空,清空随机地址的数据?AV就会出现了...

(不要想着,在GetMem后,进行每字段初始化,容易出错的就是这个,在有以上以字段的情况下,如果需要手动初始化,必须用fillchar,原因如上。)

与之相反的Dispose()亦同,反操作,进行清空:finalize(x)后,再进行FreeMem,以保证record/object中,

string,interface/dyncarray字段,不会因为直接调用FreeMem而泄露(leak)

总结是:

a: New==> GetMem(p, sizeof(TDataType)) + Initialize(p^) ==>AllocMem(sizeof(TDataType));

它与AllocMem区别是:initialize(x)不会对每个字节清0,只针对于某些字段清0.

Dispose == Finalize(p^) + FreeMem(p);

没有可代替的函数,也不能少finalize(p^)这步操作,否则会有leak.

b: record/object的指针类型,最好使用此对函数进行分配及释放。当然你也可以去自维护record/object里面的字段生存期。

c: 如果调用system.Initialize/Finalize,出现提示:

[Hint] Unit1.pas(43): Expression needs no Initialize/Finalize

表示record/object里面的字段,没有包含string,interface,dync array,variant,record,array

即表示不需要调用Initialize或Finalize进行操作。

d: 多说一句:每个warn/hint都有其作用,请勿忽略,说不定小BUG就在其中,请关注它们或干掉它们。

二:GetMem/FreeMem

GetMem/FreeMem是MM的分配与释放内存块函数,多说一些是与之相关的:此两函数,会因为分配或释放失败而抛出异常(exception)

而MM对应的标准分配与释放函数是以返回值形态进行处理的,即失败了,只会返回空值(nil)或非0,而不是异常。

也就是说Get/FreeMem是针对于MM的标准函数进行了异常封装。

异常信息:

GetMem fail => Out of memory.

分配失败,一般只会是进程的可用内存分配完毕,通常在内存泄露的情况下才会发生。

FreeMem fail => Invalid pointer operation

两次FreeMem同地址,第二次就有这invalid pointer异常了。:)

三:GetMemory/FreeMemory

Get/FreeMemory与GetMem/FreeMem基本相同,唯一不相同的是,它直接以MM的对应函数的返回值作为返回,而不进行异常处理。

即:GetMem调用MM.GetMem返回为nil,则有异常,而GetMemory则直接返回nil,交给调用者处理

FreeMem调用MM.FreeMem返回非0(错误释放),则异常,而FreeMemory则直接返回0或非0,给调用者处理。

这点非常有用,在写程序时,可以减少异常,或者在Get/Free出现错误时,写句assert(...),让程序中断下来,检查并调试。

四:SysGetMem/SysFreeMem

SysGetMem/SysFreeMem与GetMemory/FreeMemory基本相同,区别在于,它直接调用MM的实现函数,

则不是经过MM的管理器指针再行跳转。

即说:SysGet/SysFreeMem,它使用的是系统自带的MM分配释放函数,当第三方MM加入后,以上三对函数,

都会由第三方MM接管,但SysGet/SysFreeMem它还是调用的本系统自带的MM函数处理,与第三方MM无关。

五:其它

其它还有些Delphi单元的分配释放函数,不过基本是从以上四对函数扩展出来,就不说明了

当然也有从API扩展出来的分配+释放函数,则不在此列,它与D系统的MM扩展无关。

总结:

New+Dispose与GetMem+FreeMem,是基于VCL异常机制保护的分配+释放函数。

GetMemory+FreeMemory与SysGetMem+SysFreeMem是由调用者自行控制返回,来决定是否返回异常或错误处理。

delphi.memory.分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同相关推荐

  1. C#资源释放及Dispose、Close和析构方法

    C#资源释放及Dispose.Close和析构方法   备注:此文的部分观点有误,之所以仍旧保留本文,是需要在后期给出一个勘误版.正确的版本在这里"C#中标准Dispose模式的实现&quo ...

  2. 如何简化临时内存的分配与释放

    描述:在编制 C++ 程序时,最常遇到的一个令人恼火的问题便是临时资源的分配与释放问题, 由于程序的逻辑关系通常很复杂,引发异常的可能性也很多,为了妥善处理运行时异常, 我们不得不在可能引发异常的任何 ...

  3. 分配和释放 BSTR 的内存

    本文档已存档,并且将不进行维护. 分配和释放 BSTR 的内存 Visual Studio .NET 2003                  转自: https://msdn.microsoft. ...

  4. FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  5. C/C++动态二维数组的内存分配和释放

    C语言: 1 //二维数组动态数组分配和释放 2 //数组指针的内存分配和释放 3 //方法一 4 char (*a)[N];//指向数组的指针 5 a = (char (*)[N])malloc(s ...

  6. OpenCV分配与释放图像空间

     图像处理 单通道图像灰度取值 IplImage * pSrcImage = cvLoadImage("Sunset.jpg",CV_LOAD_IMAGE_GRAYSCALE) ...

  7. 利用二叉树的思想来实现分配和释放内存方法

    虽然大部分系统都有提供内存动态分配和释放函数(即C语言中的malloc和free函数),但是在嵌入式开发中由于系统的限制往往需要自己来实现内存管理,如在有些平台上可动态申请的最大空间不能满足程序设计的 ...

  8. c语言内存分配与释放 不同类别变量的内存分配和释放的区别

    1.不同变量使用内存的区别 静态存储类别的变量:内存数量在编译时确定,程序开始执行时创建,程序结束时销毁.(static.const) 自动存储类别的变量:程序进入变量定义所在块时存在,离开块时销毁. ...

  9. C++/C--动态二维数组的内存分配与释放【转载】

    1 C语言_二维数组动态数组分配和释放 1.1 数组指针的内存分配和释放 //方法一 char (*a)[N];//指向数组的指针 a = (char (*)[N])malloc(sizeof(cha ...

最新文章

  1. 配置nfs服务器出现的问题
  2. 第十二周项目1-阅读程序(三)
  3. 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”
  4. git与eclipse集成之代码冲突与解决
  5. Oracle translate 函数的用法, 以及和replace的区别
  6. 相机开发:海康板卡相机开发
  7. java基本数据类型_Java 中有几种基本数据类型是什么?
  8. ABAP Development Tool后台处理前台请求的入口
  9. 1个月增长15000 star,zx 库写shell脚本真不错~
  10. python动态获取cookie_看到很多人求助python 我也求助一下如何写cookie的获取和登录吧...
  11. # CSP 201609-2 火车购票购买(100分)
  12. centos上自动执行脚本执行php文件
  13. 诊断 Linux 服务器的性能
  14. 几款经典css框架下载
  15. DM368开发 -- 视频监控系统相关技术研究(转毕设)
  16. visual basic与python_学visual basic还是 python?
  17. 西瓜书k-means例子matlab实现
  18. 论文中的定理(Theorem)、引理(Lemma)、推论(Corollary)
  19. 阿里云思维导图系列(五)阿里云关系型数据库产品全家福
  20. 利用python获取身份证号中年龄和性别信息

热门文章

  1. Cardano(ADA)的共识算法Ouroboros
  2. 获取当前CPU的运行速度
  3. 解决Error: Could not detect Mac OS X Version from sw_vers output: '10.14.3'
  4. 电池-外部DC双电源供电设备电源自动切换电路分享
  5. QUI框架多选下拉框回填
  6. Likely root cause: java.lang.IllegalStateException: jar hell!
  7. 【枚举】CF809A
  8. Leetcode 1400:构造K个回文字符串(超详细的解法!!!)
  9. HTTP协议漫谈 C#实现图(Graph) C#实现二叉查找树 浅谈进程同步和互斥的概念 C#实现平衡多路查找树(B树)...
  10. qq在电脑上总是服务器连接中断,win7系统玩QQ炫舞老是掉线提示与服务器断开连接的解决方法...