我在程序中定义了这样一个动态数组:procedure DoSomething;
var
…
aDynamicArray: array of TAClass;
begin
…
setlength(aDynamicArray, Length);
…
for i:=1 to Length do
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
end;结果老是出错,后来把
for i:=1 to Length do
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
部分删掉就正常了,哪位知道为什么,解释一下。不显式地调用free不会造成内存泄漏吗?
var
…
aDynamicArray: array of TAClass;
begin
…
setlength(aDynamicArray, Length);
…
for i:=1 to Length do
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
end;结果老是出错,后来把
for i:=1 to Length do
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
部分删掉就正常了,哪位知道为什么,解释一下。不显式地调用free不会造成内存泄漏吗?
解决方案 »
- 请教高手,如何用dbgrid急。。。。。。。。。。。。。。。
- 请问怎么样才能使DOS窗口中的内容在Listbox中显示?谢谢!
- 带第三方ocx控件的 软件发布
- 我说开发Mis,ERP,CRM,Web比开发驱动程序或者说比与硬件较紧密相关的底层开发要难得多 ???
- 东方影都的多功能播放列表功能如何实现
- 请问如何在quickrep中把a3的纸横过来用啊
- 请问有谁知道ThemeEngine 3.1.5(实现XP效果的控件)在DELPHI7下怎么安装?
- 送分问题:什么安装工具比较好?
- 有没有可以在delphi中显示flash格式的控件
- Delphi依时利二次开发,读卡基本信息失败!
- 有谁可以帮啊我这个百思不解的难题?急!!急!!!
- DELPHI怎么实现缩略图?
"Length"不知道楼主要代表什么,它本身是Delphi的一个函数名称,如果“Length”是代表一个Integer类型的变量的话,我估计错误是数组越界了。setlength(aDynamicArray, Length);//数组定义的范围在0~Length-1
...
for i:=1 to Length do//这里越界了
...
//应该改为
setlength(aDynamicArray, iLength);
...
for i:=0 to iLength do
...
setlength(aDynamicArray, iLength);
...
for i := 0 to iLength - 1 do
...
另外关于"
不显式地调用free不会造成内存泄漏吗?"
动态数组属于自管理类型,系统会自动释放,就象string类型一样,一般情况下不需要手动释放的,即使要释放,也不是free,而是
1、将数组变量赋值为nil;
2、调用函数:finalize
begin
if Assigned(aDynamicArray) then
begin
try
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
except end;
end;
end;
…
aDynamicArray: array of TAClass;
begin
…
setlength(aDynamicArray, Len+1);
…
for i:=1 to Len do
aDynamicArray[i]:=TAClass.Create;
…
for i:=1 to Len do
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
end;又试了几次,调用free是没问题的。但如果去掉最后那个循环,会不会有内存泄漏的问题?
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; TAClass = class
c: char;
destructor Destroy;override;
end;procedure test;var
Form1: TForm1;implementation{$R *.dfm}procedure test;
var
i, n: integer;
aDynamicArray: array of TAClass;
begin
n := 1000000;
setlength(aDynamicArray, n);
for i:=1 to n-1 do
begin
aDynamicArray[i] := TAClass.Create;
aDynamicArray[i].c := 'a';
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
i:integer=0;
begin
for i:=1 to 10000 do
test;
end;{ TAClass }destructor TAClass.Destroy;
begin
//证明内存没有被释放
form1.Edit1.Text := 'free';
inherited;
end;end.
你的程序逻辑上并没有问题。
但你按下“Button1”的时候,程序Create 了10000000000个TAClass!!!
你知道这些TAClass要占用多少内存吗?你算一下吧,一个TACLass占用4个字节,它们加起来要占用9.5G的内存!!!!!!!!!!!
我不知道你的内存有多少,但是你的内存有1G的话,你还要添置9G内存才能运行你的程序!!
问题不是它没有释放内存,而是你的内存不够用(估计你没有10G的内存),还没到运行到释放内存的代码的地方,你的程序已经停止了,系统估计也要停止相应了。
我已经测试过,只要你Create TACLass的数量不超过你内存所能负担的话,完全可以被释放的。
这其中有2种情况
1.Create的时候指定了类的所有者,如:
var
sl: TStringList;
lb: TLabel;
begin
sl := TStringList.Create; //没有指定sl的所有者
lb := TLabel.Create(nil); //同样没有指定lb的所有者
...
sl.Free;//需要手动释放
lb.Free;//需要手动释放
end;2.Create的时候指定了所有者,可以不手动释放
var
lb: TLabel;
begin
lb := TLabel.Create(self);//指定了lb的所有者为self
//这种情况不手动释放都不会造成内存泄漏,它的释放由它指定的所有者self负责
//但是为了不浪费系统资源,建议还是用完lb后手动释放 lb.Free;
...
end;
问题不是它没有释放内存,而是你的内存不够用(估计你没有10G的内存),还没到运行到释放内存的代码的地方
…
Create的时候指定了类的所有者
…真是你越说我越糊涂啊。
从test过程退出时都不释放内存,什么时候才"运行到释放内存的代码"?我结束程序的时候吗?
什么叫Create的时候指定了类的所有者?你知道Create(AOwner)这个方法是哪来的吗?一个普通的类能指定所谓的类的所有者吗?
2.“Create的时候指定了类的所有者”,对于这句要你自己去体会,很难作更详细的说明;
3.有的类创建的时候可以指定所有者,有些不能指定所有者,这是类固有的;
4.如果是你自己写的类,就看你的类怎么写,指定还是不指定所有者完全有你决定。
for i:=Length To 0 Dowen do <-----------------------
begin
aDynamicArray[i].Free;
aDynamicArray[i] := nil;
end;
end;
你先看一下tobject的声明,再看看tcomponent的声明,然后再来讨论好吗?