Blue
Red
Green
Orange
Voilet
Slate
Dark

讨论与学习:返回对象的函数的内存释放问题 (300分)

J

jbas

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
fs:Tstringlist;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
fs:=tstringlist.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
fs.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
for i:=1 to 10 do
fs.Add(inttostr(i));
combobox1.Items.Assign(fs);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i:integer;
begin
for i:=20 to 40 do
fs.Add(inttostr(i));
combobox2.Items.Assign(fs);
end;

end.
 
J

jbas

Unregistered / Unconfirmed
GUEST, unregistred user!
function TForm1.test: tstringlist;
var
i:integer;
begin
for i:=100 to 200 do
fs.Add(inttostr(i));
result:=fs;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
s:tstringlist;
begin
//没有给s分配内存,需要s.free吗???????
s:=test;
combobox3.Items.Assign(s);
end;
 
J

jbas

Unregistered / Unconfirmed
GUEST, unregistred user!
错了,应该在需要用fs的时候,在其前面加fs.clear;这样好一点了。前面的忘加了,
高手们,说说这样行吗?
 
Y

ysai

Unregistered / Unconfirmed
GUEST, unregistred user!
to jbas:
我的函数要求不依赖于任何对象呢?采用
private
{ Private declarations }
fs:Tstringlist;
就不行了


procedure TForm1.Button3Click(Sender: TObject);
var
s:tstringlist;
begin
//没有给s分配内存,需要s.free吗???????
s:=test;
combobox3.Items.Assign(s);
end;
绝对会造成内存丢失的,我已经实验过,上面有代码,已经说明了,windbell更是详细说明了

关键是自释放,看样子是没法解决的了,呵
 
X

xeen

Unregistered / Unconfirmed
GUEST, unregistred user!
to ysai:
combobox2.Items.Assign(s);

combobox2.SetItems(s);

combobox2.Items = s;
三者等效.
 
Y

ysai

Unregistered / Unconfirmed
GUEST, unregistred user!
to xeen:
我知道是两个不同的对象,一个会自释放(combobox2.Items),
一个不会(函数的返回值),而重点就是在这,怎么 <<自动>> 释放!!!
PS:老兄把我的名字写错了~~~~~
 
X

xeen

Unregistered / Unconfirmed
GUEST, unregistred user!
To ysai:没法自动释放.这是由操作系统的机制决定的:你在堆上申请分配
的空间必须自动手动释放。如果没有java和.net的GC,我听说的处理方法一般都是:有一
个容器对象(可能是一个链表)里面放着你申请成功的对象的指针,在一个合适
的时机(只能自己决定)把容器中的指针和它指向对象都销毁.
 

影 子

Unregistered / Unconfirmed
GUEST, unregistred user!
好象这段时间没什么耐心,看不下回复的帖子。唉,不知道是不是睡眠严重不足的缘故。

方法一:
  没什么好说的。
方法二:
  更改function GetList:TStrings;为
procedure SetList(var Value: TStringList);
var
i:Integer;
begin
Value.Clear;
for i:=1 to 1000 do
Value.Add(IntToStr(i));
end;
在Button2Click中Create一个TStringList,用SetList修改它

方法三:
  使用了两次Getlist,但只Free一次,内存肯定会增加。

方法四,五:
  将fm.Free更改为fm.Release看看。

我所说的都没有通过验证,太累,懒得动。呵呵
 
Y

ysai

Unregistered / Unconfirmed
GUEST, unregistred user!
to xeen:
从TComponent派生是不行的,因为对像TStrings这种对象没办法,
而且我也不想为了这个目的再写一个类把TStrings包含进去.
用接口能实现吗?如果能,怎么用?
如果我有这样一个函数:
function GetRecordSet(SQLString:String):TDataSet;
可能用接口吗?
 
X

xeen

Unregistered / Unconfirmed
GUEST, unregistred user!
to ysai:
用接口来引用实现它的类可以自动释放,是通过引用计数实现的.
一个例子:
[blue]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
IMyClass = Interface
['{285DEA8A-C865-11D2-AAB7-00C04FB17A72}']
procedure MyMethod;
end;
TMyClass = class(TInterfacedObject,IMyClass)
procedure MyMethod;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
procedure TMyClass.MyMethod;
begin
beep;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
AInterFace:IMyClass;
begin
AInterFace := TMyclass.create;
AInterFace.MyMethod;
end;

end.[/blue]
AInterFace所引用的TMyClass对象将被自动释放,但由于TDataSet类没有实现任何接口,
所以这种方法不适用:-(
 
Y

ysai

Unregistered / Unconfirmed
GUEST, unregistred user!
无解~~~~~
最后采用 一个过客 的方法
声明如下
function GetRecordSet(SQLString:String):TDataSet;overload;
function GetRecordSet(SQLString:String;var DataSet:TDataSet):Boolean;overload;
为了兼容以前的代码重载了这个函数
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
668
import
I
顶部 底部