那位大哥帮帮忙,给解决一个简单问题(150分)

  • 主题发起人 主题发起人 vvyang
  • 开始时间 开始时间
V

vvyang

Unregistered / Unconfirmed
GUEST, unregistred user!
各位达人帮帮忙,关于 Initialize 和 Finalize 的问题...
type
TVector = record
id: Integer;
text: string;
elems: array of Integer;
end;
PVector = ^TVector;

var
pv: PVector;
p: Pointer;
begin
GetMem(pv, SizeOf(TVector));
Initialize(pv^);
//问题在这,是写 Initialize(pv^) 还是分别写 Initialize(pv^.text)、Initialize(pv^.elems)?
//Delphi 能判断 TVector 中有那些是动态数组么?
//如果能判断,那我换成下面的写法 Delphi 还能判断么?
//p := pv;
//Initialize(p^);
end;

区区 150 分不成敬意...
 
用new(pv)不好吗?
 
指针用New和Dispose来创建和释放就行了
 
用一个 Initialize,在 Initialize 中除了给 pv 分配内存外,还必须给 pv.text,pv.elem 分配内存。
 
To Avalon & jennykiller:
New(p) 的前提是必须确定指针 p 的类型,而我的情况是 p^ 的类型不固定...
再解释一下,我实际遇到的情况是 Dispose 的问题,就是 Dispose(p) 中 p^ 的类型不确定,而且 p^ 中含有动态数组;而用 FreeMem(p) 同样只能释放掉 p^ 占据的空间,不能释放掉 p^ 中的动态数组。我想用一个通用的过程释放掉不同类型记录所占据的空间,因为事先都是都是用 GetMem(p, nSize) 分配的,所以用 FreeMem(p) 不必知道具体记录的大小,有可能将这个过程用一个 Finalize + FreeMem 表示 ...
 
你的意思是你的p可能是指向不同结构的指针??
 
To Avalon:
没错...
因为 Windows 和 Delphi 有内存管理,就可能出现下面的写法:

var
p1: ^TVector1;
p2: ^TVector2;
begin
GetMem(p1, SizeOf(TVector1));
GetMem(p2, SizeOf(TVector2));
....
//而释放呢,只用同一句就行了:
FreeMem(p1);
FreeMem(p2);
//棘手的是 TVector1 和 TVector2 中都含有动态数组,不好写成一个通用过程
//如果 Finalize 管用的话就可以写成:
//Finalize(p^);
//FreeMem(p);
end;
 
以前做过类似 那个时候是对不同结构 都设置一个标志成员来对应释放的动作

通用方法看来等楼下的牛人了[:D]
 
To kaida:
如果记录中不含有动态数组,只用 FreeMem 就行了,不用 Finalize...
关键如果含有动态数组,用 Finalize 不知道还能不能起作用?
 
To 大家:
验证了一下,自己解决了...
无论是 New()、Dispose() 还是 Initialize()、Finalize(),都需要显示地指定指针的类型,否则不能正常进行初始化或释放。
如 Initialize() 必须写成 Initialize(PVector(p)^) 之类的。
看来通用方法是不可能的了,郁闷ing...
 
New最简单了。 如果要知道结构中的元素类型,得用typinfo单元的方法。
 
To duhai_lee:
实际上 New() = Initialize() + GetMem();
对于不含有动态数组类型的记录,直接用 GetMem 更简单、高效。
 
谢谢各位,把分分了...
 
后退
顶部