New 和 GetMem 的不同之处

LoRA学习: SX1276/SX1277/SX1278对比 Lora芯片 SX1276/SX1277/SX1278的比较SX1276/7/8是一种半双工传输的低中频收发器,配备标了标准FSK和远距离扩频Lora调制解调器。该芯片可以用于超长距离的Lora扩频通信,并且抗干扰性强,同时达到低功耗要求。1、芯片关键参数对比: 可以看出SX1276的带宽范围为 7.8~500kHz ,扩频 因子6~12,并覆盖所有可用频段。 SX1277的带宽和频段方位与 S 阅读详情

如果操作一个 record 指针中的字符串变量,会不会丢失 string 的内 存空间,造成内存泄漏?

结果是:使用 New() 分配的内存,会自动初始化 record 的内容,并且在 Dispose 时自动 清除所有已分配的内存,包括 string 或其他动态数组的内存。GetMem/FreeMem 没有这个 性质。事实上,New() 中调用了 GetMem,并且执行了一些初始化的操作。

代码如下:

type PMyRecord = ^TMyRecord;

TMyRecord = record

I: Integer;

S: string;

V: Variant; end

; {;$DEFINE NEW}

 procedure TForm1.Button1Click(Sender: TObject);

 var R: PMyRecord;

I: Integer;

 begin

for I := 1 to 1024 do

begin

{$IFDEF NEW} New(R); // 正确将 R.S 初始化

SetLength(R.S, $FFFF); Dispose(R); // 正确释放 R.S 内存空间

{$ELSE} GetMem(R, SizeOf(TMyRecord));

R.S := ''; // 出错 SetLength(R.S, $FFFF);

FreeMem(R);

{$ENDIF}

end;

end;

GetMem 只负责分配空间,不会负责清空刚分配的空间,如果需要分配来就 清空的空间可以用 AllocMem,AllocMem = GetMem + FillChar。

我上面犯错误了,以为 S = 0 时也会出错,所以没有 FillChar,其实不会。 这样就可以正确测出结果了: (将 $DEFINE NEW 前面的 ; 去掉,可以从任务管理器中查看二种方法的内存占用)

 type PMyRecord = ^TMyRecord;

TMyRecord = record

I: Integer;

S: string;

V: Variant;

end; {;$DEFINE NEW}

procedure TForm1.Button1Click(Sender: TObject);

var

R: PMyRecord;

I: Integer; begin

 for I := 1 to 1024 do

begin

{$IFDEF NEW}

New(R); // 正确将 R.S 初始化

SetLength(R.S, $FFFF); Dispose(R); // 正确释放 R.S 内存空间

   {$ELSE}

GetMem(R, SizeOf(TMyRecord));

FillChar(R^, SizeOf(TMyRecord), #0);

SetLength(R.S, $FFFF); FreeMem(R); // 不会释放 R.S 内存空间 !!

{$ENDIF}

end;

end;

是的,FreeMem 不会释放其中的生存期自动管理的内容,因为在 FreeMem 看来,那些都是一致的二进制数据,没有任何意义可言。不过可以通过一个 Finalize 调用(或者 FinalizeRecord)解决该问题。Dispose 就直接 或间接调用了 Finalize,帮助中明确地说明:            

In Delphi code, FreeMem destroys the variable referenced by P and returns its memory to the heap. If P does not point to memory in the heap, a runtime error occurs. If P points to a structure that includes long strings, variants, dynamic arrays, or interfaces, call Finalize before calling Freemem. ...... Note: It is preferable to use the New and Dispose procedures rather than GetMem and FreeMem. When using New and Dispose, there is no need to explicitly call Finalize.

“在DELPHI代码中,FreeMem根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误。如果指针所指向的是一个数据结构,且其中包含有长字符串、Variants、动态数组、或接口,则在使用用FreeMem之前须调用Finalize ” "注意:使用New 和 Dispose 过程要强于使用GetMem与FreeMem。但我们使用New和Dispose的时候,不需要显示的调用Finalize "

在这里,我们讨论指向结构体的指针,在这种情况下,New/Dispose 通常是易用的。但是它们是有局限的,就是那个指针指向的空间的大小必须能够在编译期间确定,它们才知道需要分配多大的空间。对于指向结构体的指针,这个值就是结构体的大小,这当然是确定的,所以能够使用它们,并且能够带来便利。 可是还有一些情况,例如你只有一个 Pointer 类型,这是无类型指针,你把它传给 New,编译器就不知道它指向的是什么内容,也就不知道它指向的空间有多大,也就不知道需要分配多少空间,就根本不能用,更不用说易用了。New/Dispose 操作更为高层一些,我们通常用它们来操作指向结构体的指针,即是说指针指向的内容是编译期间就已知的数据结构。而当我们需要更加低级的去操作一些内存空间的时候,比如你要自己处理字符串的时候,你的指针指向的就是只有你自己才知道或者说是你自己去进行理解的内存空间,没有编译期间的明确的数据结构与之对应。这个时候,就要用到 GetMem/FreeMem 了。 所以说,New/Dispose 的局限性实际上是很大的,或者说适用范围是很小的,而 GetMem/FreeMem 给了我们充分的自由,试用范围更广。当然,具体选用哪个,还要看实际情况而定。

米花同城社区 6.6.4 后台模块+小程序前端源码分享 米花同城社区 6.6.4 后台模块+小程序前端源码分享,有需要的朋友下载 立即下载

相关推荐

使用c语言写的卷积运算程序

标准C语言计算卷积的公式,在VC下编译通过

[Delphi]内存分配和释放 内存操作函数(4): 清空与填充内存

FillMemory、ZeroMemory 一目了然的两个函数, 但其实它们都是调用了 FillChar; 清空不过就是填充空字符(#0: 编号为 0 的字符), 说来说去是一回事. 为了下面的测试, 先写一个以十六进制方式查看内存的函数: function GetMemBytes(var X; size: Integer): string; var   pb: PByte;

ly930156123的博客 7967

CAD图中删除重复实体

加载在CAD里,删除所有重复的东西,重复的文字,重复的块,重复的线段,重复的实体

[delphi]New 和 GetMem 的不同之处

New 和 GetMem 的不同之处2006-12-23 14:56如果操作一个 record 指针中的字符串变量,会不会丢失 string 的内 存空间,造成内存泄漏? 结果是:使用 New() 分配的内存,会自动初始化 record 的内容,并且在 Dispose 时自动 清除所有已分配的内存,包括 string 或其他动态数组的内存。GetMem/FreeMem 没有这个 性质。事实上,Ne

1575

C语言课设图书馆图书管理系统

C语言课设做的一个图书管理系统,非常适合,大一大二C语言课设使用,非常简单明了。

控制台用户管理系统

一个初学者写的控制台用户管理系统,面向对象开发,使用java语言

New 和 GetMem 的不同之处====转帖收藏

 如果操作一个 record 指针中的字符串变量,会不会丢失 string 的内 存空间,造成内存泄漏?结果是:使用 New() 分配的内存,会自动初始化 record 的内容,并且在 Dispose 时自动 清除所有已分配的内存,包括 string 或其他动态数组的内存。GetMem/FreeMem 没有这个 性质。事实上,New() 中调用了 GetMem,并且

henreash的专栏 1229

NPAPI 安全输入控件

基于NPAPI开发的安全输入控件,已经在Firefox、chrome、opra、maxthon浏览器下测试通过~!

Delphi New,Getmem,ReallocMem联系与区别

转自博客园http://www.cnblogs.com/jsrgren/archive/2011/10/31/2270353.html procedure New(var P: Pointer);  {为一个指针变量分配内存,会自动计算指针所指数据结构需要空的空间大小} procedure GetMem(var P: Pointer; Size: Integer); {分配一个指定大小的内

找个地方放一下 4648

DSP实验报告——模拟信号的AD+FFT变换

一份完整的DSP实验报告,对模拟信号进行AD+FFT变换。含源代码(C语言),基于ICETEK-VC5509-A-USB-EDU实验箱,中南大学的同学可以下载直接使用。其他院校的可以下载作为参考资料,。

Python爬虫实战:西瓜视频m3u8解析与FFmpeg下载合并

网络爬虫与流媒体解析是Python工程实践中的常见需求,其核心在于通过HTTP请求获取数据并解析特定格式。m3u8作为HLS协议索引文件,将视频切分为ts分片,便于流式传输。结合FFmpeg的多线程处理能力,可高效完成分片下载与合并,技术价值在于提升视频处理效率。典型应用场景包括视频下载、离线缓存等。本文以西瓜视频为例,详细讲解如何使用requests库提取m3u8地址,并调用FFmpeg批量下载ts分片合并为mp4,涵盖请求伪装、索引解析及常见问题排查。

weixin_31856057的博客 15万+
上一篇: 首篇中肯的文字
下一篇: delphi中TreeView使用
曹牧
博客等级 码龄22年 396粉丝 762原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值