关于动态数组与 SetLength() 函数(50分)

  • 主题发起人 主题发起人 3h
  • 开始时间 开始时间
当然用TList, Tlist有单链表结构全部功能, 尤其对数据的插入、删除
交换、排序、压缩(Pack)等操作有很高的效率. 同时还有高效的排序方案(你
只需要传送一个比较函数指针变量给Sort过程就行了.

可变数组的效率不如它, (不过, 编译器对可变数组有可能是通过链表实现的,
否则程序实现时很难找到一块任意大小的, 连续的内存空间来存放数组.)

粗略的看了你的程序, 下面的操作应该会发生问题.
fr := @(hhhftp1.FileList)

(因为你正在访问一个私有变量FileList

同时对一个Property 进行地址操作是不安全的, 它得到的不是你想要的东西.
得到的可能是某个函数的地址 , @操作符只可以对变量进行操作.

你的程序中 TFileReco 完全可以用TList来实现, 而且效率高高...

(大量的程序控件都是用的TList实现的, 这已经成为这类问题的标准解决方案)

你参照一下Tlist中的Add的例子. 改造一下HHHFTP控件. 不明白的地方说出来。
大家帮你解决, 这个控件问题用Tlist解决是很Easy的事。

不过要小心, HHHFTP变成SEASKYFTP就不妙了。 :)) .

再提醒你一点,看看关于数组属性在VCL类中的标准方法吧。

 
有两点 补充一下,
可变数组在大幅度变换数组长度时, 有明显的方便和易用性。(你的
情况不适合)。

Tlist释放时, 要将每个Item所指向的分配内存间都要
进行显式的释放。 (在HHHFTP的Destroy中做〕。
 
看来是非用 TList 不可了。其实这个控件是想测试、试验一下写控件的味道,得到朋友们这么热情的帮助,真是“感激涕零”啊!

现在问题已基本上明朗了,就差一个试验了。
等我回家试通过了就给分!
 
to seasky:
关于 TList 的节点的显式释放,我个人觉得用
Reco : TList;
...
Reco.Clear;
这样似乎更直接,不知道您的意思如何?
我试过这样:
procedure THHHFTP.ClearList;
Var
I : Integer;
Reco : ^TFileReco;
begin
I := FFiles.Count-1;
While I >= 0 do
begin
Reco := FFiles.Items;
Dispose(Reco);
Dec(I);
end;
end;
结果不正确,提供非法指针操作。

To 另一只眼:
1的原因是因为对动态数组的操作出错。
 
看似直接, 其实不行. list.clear只清除list中存放各个指针的空间, 至于原来这些指针指向
的地方, list.clear可不会自动清. (我就常把list.items作为一个整数使用, 如果
list.clear会自动跟踪到items指向的空间并清除这区间早出乱子了), 所以光用list.clear
回造成内存泄露(也许退出程序时windows会回收, 但在程序运行时这些空间就无法再使用了).
 
那上面的程序在那里出错呢?
 

问题可能出在你的 add 过程 ,

你将新的Item add 的过程贴一下,

Another_eyes所说的为什么不能直接用Clear, 是对的。
Item中只存放指针量, 程序无法知道Item指的是什么类型。

另外, 按着eyes的意思, 你试着将

TFileReco = Record
SFileName, SFileFullName : String;
^^^^^^^^^^
....
end;
中的String换为定长度的字符串 。 如 String[40].




 
我已将它改为 LIST 了。
记录基本没改:
type
TFileReco = Record
SFileName, SPath: String;
FileSize : Integer;
FileAttrib : Integer;
FileDateTime : TFileTime;
IsDir : Boolean;
end;

ADD 的过程如下:
Function AddToArray(Const W32FD: TWin32FindData
Var List: TList) : Integer;
Var
PItem : ^TFileReco;
Dir : String;
begin
Dir := FCurDir;
If Dir[Length(Dir)] <> '/' then
Dir := Dir + '/';
New(PItem);
With PItem^ do
begin
SFileName := String(W32FD.cFileName);
SPath := Dir;
FileDateTime := W32FD.ftLastWriteTime;
FileAttrib := W32FD.dwFileAttributes;
FileSize := (W32FD.nFileSizeHigh * MAXDWORD) + W32FD.nFileSizeLow;
IsDir := ((FileAttrib and faDirectory) <> 0);
end;
List.Add(PItem);
Result := List.Count;
end;
 
我知道你的问题出在哪.
不在add中, 在clearlist中
在你的clearlist最后(循环外)加上一句:
ffilelist.clear;
 
不早说!:)
 
此问题也告一段落了,这50分就给cytom、CJ、amo分了吧,
another_eyes &amp
seasky 请到<a href="DispQ.asp?LID=137258">另一问题</a>拿分请笑纳。
 

Similar threads

后退
顶部