Blue
Red
Green
Orange
Voilet
Slate
Dark

如何知道一个类已经释放?(40分)

F

fuliang

Unregistered / Unconfirmed
GUEST, unregistred user!
对于
var S:TStringList;
如何知道,它是否创建了,又如何判断它已经释放了?
用assigned(s) 是判断不了它已经释放了的.
 
P

pegasus

Unregistered / Unconfirmed
GUEST, unregistred user!
从原理上说, S只是一个指针, 因此很难知道她所指向的地方是否是一个创建好的对象,
或者指向的对象是否已经释放了.
合理的方法是:
给S赋初值为Nil;
释放S对象之后, 在给S赋Nil.
这样, 只要没有多个指针同时指向同一个对象, 您就可以通过
判断该指针是否为Nil来指导对象是否创建或清除了(还未创建)

如果有多个指针指向同一个对象, 那么避免清除不是自己创建
的对象, 可以减少发生错误的可能性
 
F

fuliang

Unregistered / Unconfirmed
GUEST, unregistred user!
; 这个方法我想过,但是解决不了我的问题.
我建立了一个对象的数组,是TThread的数组.
在线程退出时,自动释放了TThread对象,
我访问这个数祖时,就不知道这个对象是不是释放了.

有没有好的办法知道对象释放了?也就是判断
指针是不是指向一个合法的地址?
 
J

jiangtao

Unregistered / Unconfirmed
GUEST, unregistred user!
使用Win32的函数isBadReadPtr,可以检查是否合法分配数据pointer?
assigned只是判断是否为nil
 
F

fuliang

Unregistered / Unconfirmed
GUEST, unregistred user!
IsBadReadPtr 带有两个参数,一个是指针,另一个是监测的数量.
第二个参数改写多少呢? 写1 或写10 都是监测不出来的.
 
P

pegasus

Unregistered / Unconfirmed
GUEST, unregistred user!
To jiangtao:
>使用Win32的函数isBadReadPtr,可以检查是否合法分配数据>pointer?
>assigned只是判断是否为nil
这种方法不能保证可靠性, 因为您用new, dispose不是直接向操作系统申请/释放内存, 而是通过编译器连接在程序内的堆管理
模块进行的. 堆管理模块不会立即把空闲的内存释放给操作系
统, 也就是说, 对您的程序来说, 这块内存已经释放了, 但是对于
操作系统来说, 这块内存还被您的程序中的堆管理模块占用.

To fuliang:
>我建立了一个对象的数组,是TThread的数组.
>在线程退出时,自动释放了TThread对象,
>我访问这个数祖时,就不知道这个对象是不是释放了.
我建议您建立Thread时, 用suspend方式, 把它挂起来, 然后
在您的数组中给它找一个空闲位置记录下来, 并把这个位置
也记录到Thread的某个成员中去, 这样, 当Thread结束时, 可以
访问您的数组, 把相应位置的值置为空闲状态. 这个方法需
要同步以避免多线程同时对一个数据结构的读写操作.

更好一些的方法时把您的线程的FreeOnTerminate置为False(缺省值)
退出之前给主程序发送消息, 然后由主程序负责Free这个Thread
 
P

pegasus

Unregistered / Unconfirmed
GUEST, unregistred user!
To fuliang:
>, 当Thread结束时, 可以访问您的数组, 把相应位置的值置为空
>闲状态. 这个方法需要同步以避免多线程同时对一个数据结构
>的读写操作.

嗯, 您可以在Thread的OnTerminate事件处理过程里进行这项工
作, 这时不会造成冲突
 
F

fuliang

Unregistered / Unconfirmed
GUEST, unregistred user!
pegasus:
我采用了您的把FreeOnTerminate置为False的方法。
释放工作在主线程里做,我觉得这是最简单的方法。
谢谢您的回答。

顺便再问一下,难道就没有判断对象已经释放的方法么?
 

Similar threads

顶部 底部