定义了一个类用来判断编号是否存在,但运行时出错:access violation at address ******** in module 'Project1.exe'.Read of address 00000004.
出错的代码如下:
function Tbasedata.CheckRec(Id:string):Boolean;
begin
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false
else result:=true;
end;
部分代码:
constructor Tbasedata.create ;
begin
Datamod:=TDM.Create(nil);
end;destructor Tbasedata.Destroy ;
begin
freeandnil(Datamod);
inherited;
end; function Tbasedata.GetIdLists():TStrings;
var
id:string;
idrec:TStrings;
begin
idrec:=TStringlist.Create ;
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add('select * from user_base');
Datamod.ADOINF.Open;
while not Datamod.ADOINF.Eof do
begin
id:=Datamod.ADOINF.fieldbyname('worker_id').AsString;
idrec.Add(Id);
Datamod.ADOINF.Next;
end;
result:=idrec;
end; function Tbasedata.CheckRec(Id:string):Boolean;
begin
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false
else result:=true;
end; function Tbasedata.GetArcId(WorkId:string):string;
begin
Datamod.ADOINF.Close ;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+WorkId+'''');
Datamod.ADOINF.Open ;
result:=Datamod.ADOINF.fieldbyname('archives_id').AsString;
end;
出错的代码如下:
function Tbasedata.CheckRec(Id:string):Boolean;
begin
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false
else result:=true;
end;
部分代码:
constructor Tbasedata.create ;
begin
Datamod:=TDM.Create(nil);
end;destructor Tbasedata.Destroy ;
begin
freeandnil(Datamod);
inherited;
end; function Tbasedata.GetIdLists():TStrings;
var
id:string;
idrec:TStrings;
begin
idrec:=TStringlist.Create ;
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add('select * from user_base');
Datamod.ADOINF.Open;
while not Datamod.ADOINF.Eof do
begin
id:=Datamod.ADOINF.fieldbyname('worker_id').AsString;
idrec.Add(Id);
Datamod.ADOINF.Next;
end;
result:=idrec;
end; function Tbasedata.CheckRec(Id:string):Boolean;
begin
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false
else result:=true;
end; function Tbasedata.GetArcId(WorkId:string):string;
begin
Datamod.ADOINF.Close ;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+WorkId+'''');
Datamod.ADOINF.Open ;
result:=Datamod.ADOINF.fieldbyname('archives_id').AsString;
end;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false//建议这儿用 if Datamod.ADOINF.isempty ..
else result:=true;
destructor Tbasedata.Destroy ;
begin
freeandnil(Datamod);
inherited;//这一句就不用了。前面都把实例释放了,这一句就引起了内存访问错!
end;
function Tbasedata.CheckRec(Id:string):Boolean;
begin
Datamod.ADOINF.Close;
Datamod.ADOINF.SQL.Clear;
Datamod.ADOINF.SQL.Add(' select * from user_base where worker_id='''+Id+'''');
Datamod.ADOINF.Open ;
if Datamod.ADOINF.Eof then result:=false
else result:=true;
end;
部分代码:
constructor Tbasedata.create ;
begin
Datamod:=TDM.Create(nil);
//---这个查询组件也要动态创建的。
adoinf:=tadoquery.create(datamod);
adoinf.parent:=datamod;
end;Datamod中的ADOINF(adoquery)是动态创建的吗?
如果是,那在上面的构造方法中,只看到你创建了数据模块TDATAMODAL;没有看到你创建查询组件啊,而你在查询方法中用到了这个组件。呵~~,就是“未创建对象实例,却访问这个对象”引起内存访问错。
从你的代码来看,只有这个问题会导致内存访问错了。
你的代码操作是正确的。从你的代码来看,你动态创建的列表 idrec:TStrings;是一个局部的对象,
这个对象只在你的方法: function Tbasedata.GetIdLists():TStrings;内才有效。
但你的返回一个列表,也就是返回一个对象指针。
实际上你的方法:GETIDLISTS()最后一代码:Result:=idrec,只是使你的函数返回值的指针指向了这个局部对象,当这个函数执行完毕后,你所创建的局部对象:idrec就不存在了。
因为:
局部对象的生存周期与这个方法的生存财期相同!
若这个方法完成后返回,则它所拥有的局部变量的内存都将回收!
当你在后面访问这个列表中的成员时,你所访问的成员地址就是不存在的!可以这样改一下:
function Tbasedata.GetIdLists():TStrings;
var
id:string;
//idrec:TStrings;这个就可以不需要了。
begin
Result:=TStringlist.Create ;
......