请教:定义了一个全局TStringList变量,程序中有几个地方clear,add了等,是不是会内存分配有问题? ( 积分: 30 )

  • 主题发起人 主题发起人 net_morning
  • 开始时间 开始时间
N

net_morning

Unregistered / Unconfirmed
GUEST, unregistred user!
有个很奇怪的问题,子窗口调用父窗口的函数,函数中如果有memo1.lines.add等,就会出现access violation 错误,找不出原因,怀疑是那个全局TStringList变量的问题。这个变量我是在creat事件里面create,在onDestroy事件中free,中间有几个地方经常代码clear,add,indexof,delete等
 
我是在creat事件里面create,在onDestroy事件中free--------谁的create事件,谁的free。
中间有几个地方经常代码clear,add,indexof,delete等------是memo1,还是TStringList?
memo1和TStringList应该是两个东西,不会发生关系。clear,add,indexof,delete 最容易发生错误的是delete,查看一下它的删除标号。
 
是TStringList,memo1只是为了显示用,调试方便。
是不是这样的原理:TStringList create后,分配一个区域,比如20大小,那么给它add几个数据,下次clear后,又add几个数据,那个区域有可能越界了?无数次clear,add后,那个区域是不是乱了?好像不应该啊,memo.lines也是TStringList类型的,clear,add无数次都没有任何问题。
 
如果你是Tstringlist --> memo.lines ,用不到创建了。但memo.lines是tstrings, TStringList = class(TStrings).
如果你是tstringlist 是实例,只是用来和memo1数据传递的缓存,两者经常交换数据。那要查查代码了。有的时候越界不立刻报错,等过程完成后才会出来。
 
看来TStringList做全局变量,中间代码中有用到Clear的,得先Free,再Create
 
可能TStringList不适合做全局变量。
我做了个最简单的测试,编译OK,运行时执行到creat出错,内存冲突的错误。
代码如下:
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure MyTest(var xyz:TStringList);
end;

var
Form1: TForm1;
gtstest: TStringList;
implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.MyTest(var xyz: TStringList);
var
i:Integer;
s:string;
begin
for i:= 0 to xyz.Count -1 do
begin
s:=xyz.Strings;
memo1.Lines.Add(s);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
aChild:TForm2;
begin
aChild := TForm2.Create(Self);
aChild.ShowModal;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage('before');
gtstest.Create;
ShowMessage('after');
end;

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

end.
=============
unit Unit2;

interface

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

type
TForm2 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation
uses Unit1;
{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var
lst:TStringList;
i:Integer;
begin
lst:=TStringList.Create;
try
for i:=1 to 10 do
lst.Add('a'+IntToStr(i));

Form1.MyTest(lst);
finally
lst.Free;
end;
end;
end.
 
ShowMessage('before');
gtstest.Create; // 这里范了低级错误 ,应该是 gtstest:= TStringList.Create;

ShowMessage('after');
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部