程序中报错,不知道错在哪,也不知道为为什么错,请高手指出并给讲讲原因,谢谢。 ( 积分: 200 )

  • 主题发起人 主题发起人 hegyi
  • 开始时间 开始时间
H

hegyi

Unregistered / Unconfirmed
GUEST, unregistred user!
我在程序中定义了以下类
TSimpleClient = class(TObject)
UserID:Integer;
timerRemain:integer;
Thread:pointer;
end;

有一个ListView,以下是增加项的过程,目的是将Treeview的Item与线程互相关联
procedure TServerMgmt.AddAUser(ComBlock:TComBlock;AThread: TIdPeerThread);
var
l:TlistItem;
Client:TsimpleClient;
begin
……
l:=lvUsers.Items.Add;
Client:=TSimpleClient.Create;
client.timerRemain:=20;
Client.Thread:=Athread;
l.Caption:=inttostr(comBlock.SendID)
//列出在线人员的ID号
……
l.Data:=pointer(Client); //挂到Item上,便于通过Item直接找到连接线程(Athread)
Athread.Data:=l
//以便根据Athread可以直接找到Item
end;

在Listview的Item删除时,应当清理内存:
procedure TServerMgmt.lvusersDeletion(Sender: TObject
Item: TListItem);
var
Client:TSimpleClient;
aThread : TIdpeerThread ;
begin
if item.Data=nil then exit;
Client:=TSimpleClient(Item.data) ; //应当是Client:=Pointer(Item.data)?
aThread:=TIdpeerThread(Client.Thread);
aThread.Connection.disConnect;
aThread.Data:=nil;//aThread.data实际上应当等于Item,去掉关联。也许没必要。
Client.Thread:=nil;
Client.Free; //这里报错!
item.Data:=nil;
end;
 
你已经nil了怎么还要Free啊?
nil的意思就是设置成空了,再Free的话当然出错了,引用了不存在的地址。
Free就可以了
 
释放一个不存在的对象当然出错
 
有个用TLIST的,不是TLISTVIEW,供参考:
http://topic.csdn.net/t/20040630/12/3134046.html
 
报什么错?
请注意提问方式!
 
首先回答是否“应当是Client:=Pointer(Item.data)”的问题:
其实你的写法已经对了:Client:=TSimpleClient(Item.data) ;这是最好的写法,因为Item.data里面存放的是pointer类型,该类型实际指的是TSimpleClient类型,因此在赋值给Client的时候,这样写清晰明了,非常好!当然如果写成Client:=Pointer(Item.data)方式也可以,因为此时实际指的就是TSimpleClient对象实例。
其次:抛开aThread类的实际操作,我看不出这几句程序:
aThread.Data:=nil;
Client.Thread:=nil;
Client.Free
//这里报错!
item.Data:=nil;
有何错误,因为aThread.Data:=nil;并不是指的FreeAndNil(aThread.Data),即从内存中释放掉aThread.Data,而是仅仅将aThread.Data原来指向的对象不再指向了,即去掉指向而已,并没有内存释放操作,同理: Client.Thread:=nil;和 item.Data:=nil;也是这个道理。
但是为什么在Client.Free;这句中出错,我认为是你的类的Destroy析够函数有问题,亦或者是对aThread对象的操作不当所引起的,这就需要看一下Client的类的析够函数了。
 
to:xingkong97
你的回答使我明白了许多,特别是明白了Client:=TSimpleClient(Item.data) 与Client:=Pointer(Item.data)的关系,我一直以为这两都是不一样的,以为后者是指针(Item.data)的指针。谢谢。
我的Client是TsimpleClient类,就在上面写明了,没有自定义的析构函数,应当是使用的TObject类的析构函数。
To:All
我的出错信息不大好写出来,但可以肯定是对一个未初使化的对象或者空指针进行操作,才会出现类似的错误,“地址XXXXX不能为Write”之类的。我就不知道,我上面的Client.free可能对空对象进行操作吗?,或者,Client本身就是空的?难是在赋值操作时错了,Client指向了一个未知内存块了?请高手帮忙看看上面的代码,谢谢先。
 
你的初始化操作是对的。你的赋值操作也没有错啊。
把这一句Client.Free
去掉还报错吗?
 
解决了吗
 
还没有解决
目前正在使用另一变通办法
 
你的TSimpleClient 的Destroy是怎么写的,把代码贴上来
 
Client.Thread:=nil;这个释放要由Client来做,不能在这里做
对于这个Thread,只能是开始退出运行暂停几个状态的调整
Client.Free
//这里报错!
 
没动静了?
 
谢谢大家参与。我的问题虽然没有在这里解决解决,但大家的分析对我还是很有帮助。
在实践中,我发现,问题其实出在Indy10本身,开源,实在太难用了!

还是结了吧
 
后退
顶部