谁来看看这个‘杂碎’(50分)

L

lili365

Unregistered / Unconfirmed
GUEST, unregistred user!
有如下代码(将表中的记录显示在TreeView中),但的关闭窗口时却报错:
procedure TForm1.Button1Click(Sender: TObject);
var
TmpSql:string;

begin
If Adoquery1.State<>dsInactive then
Adoquery1.Close;

Adoquery1.SQL.Clear;

TmpSql:='Select * From CardType Where Father is null';
Adoquery1.SQL.Add(TmpSql);
Adoquery1.Open;


Adoquery1.First;
While Not Adoquery1.Eof Do
Begin
new(p);
p^.CardType:=Adoquery1.Fieldvalues['CardType'];
p^.Name:=Adoquery1.Fieldvalues['Name'];
TreeView1.Items.AddObject(nil,p^.Name,p);

Adoquery1.Next;
End;
end;
在执行下面的代码:
procedure TForm1.Button2Click(Sender: TObject);
begin

// FreeAndNil(p);
Adoquery1.Close;
Close;
end;
出现如下的错误:

‘Access violation at 0x6a3bd8b6;read of address 0xfeeefef6’,Process Stopped,Use Stop Orun to continue.
请大侠指点,问题在那里
 
new 没有对应的 dispose


new(p);
p^.CardType:=Adoquery1.Fieldvalues['CardType'];
p^.Name:=Adoquery1.Fieldvalues['Name'];
TreeView1.Items.AddObject(nil,p^.Name,p);
dispose(p) ///////////////////////加上此句试试
Adoquery1.Next;
 
P是不是有可能根本未new过
 
1、Dispose没有通过
2、我想New肯定是作了,否则我无法正确显示

我觉得问题可能在关闭时,一些节点仍在内存中,没有释放造成的,所以应该在关闭时
作文章,请大家提供思路。
 
TreeView1.Items.AddObject(nil,p^.Name,p);
//if object is nil then error//不用赋指针,
TreeView1.Items.AddObject(TTreenode,p^.Name,p);
 
上面的阿g,我试了一下仍不可以唉
 
应该是此句的问题:
TreeView1.Items.AddObject(nil,p^.Name,p);
用的是 p所指地址,不能马上释放。
程序退出前应把TreeView1中的object 先释放掉。
 
我的理解也是这样,那如何释放TreeView的Object呢?
 
While Not Adoquery1.Eof Do
Begin
new(p);
p^.CardType:=Adoquery1.Fieldvalues['CardType'];
p^.Name:=Adoquery1.Fieldvalues['Name'];
TreeView1.Items.AddObject(nil,p^.Name,p);
p.free;
Adoquery1.Next;
End;
试试吧,应该是这个问题。
 
上面的py,你看看jsxjd先生的解析(我已试过,没有成功),我的问题是在关闭时报错的,目前
只有jsxjd朋友最后说的有道理,但我在释放TreeView的Object时,shizh没有成功,语句如下:
procedure TForm1.Button2Click(Sender: TObject);
Var
i:integer;
begin
For i:=1 To (TreeView1.Items.Count) Do
TreeView1.Items.Delete;
FreeAndNil(p);
Adoquery1.Close;
Close;
end;
 
这个(TreeView1.Items.clear)不行的话先执行下面的循环:
Dispose(Treeview1.Items.Data);
 
我觉得楼上说的对!
 
在TreeView1.Items.clear之前一定要dispose(TreeView1.Items.data),看看帮助就
知道了:
Note:The memory referenced by Ptr is not freed when the tree nodes object is freed.

必须要手工释放,否则在关闭程序时要出错的!
 
这样绝对不错:
procedure ClearNode(FTV:TTreeView);
var
i:integer;
begin
try
FTV.Items.BeginUpdate ;
for i := 0 to FTV.Items.Count -1 do
if FTV.Items.Data <>nil then dispose(FTV.Items.Data );
FTV.Items.Clear ;
finally
FTV.Items.EndUpdate ;
end;
end;
我用TTreeView都要用data属性的,所以我都是用这个过程来清除node的!
 
顶上的匕首:
你的代码思路很清晰,也很简洁,但我用了以后仍然报同样的错误,难道不是这个原因造成
的?请再帮看看。
 
看看我写的释放树型节点指针的函数:
function funFreeTreeViewNodeData(aNode: TTreeNode): integer;
var
p: Pointer;
begin
//Result := -1;
if Assigned(aNode.Data) then
begin
try
p := aNode.Data;
Dispose(p);
aNode.Data := nil;
except
on E : Exception do
Application.MessageBox(PChar(E.Message), '释放树型节点指针(Data)时发生错误', 0);
end;
end;
Result := 1;
end;
我使用的方法是在TTReeView 的 OnDeletion 事件里使用这个函数,这样当你调用节点的
delete方法是就自动执行它,以保证不会有内存泄漏。TListView也一样的道理。
 
procedure TForm1.Button2Click(Sender: TObject);
var p:^你的指针类型;//请定义成与上面加入时的p一样的有类型指针,而不是定义成Pointer的无类型指针.
i:Integer;
begin
For i:=0 to TreeView1.Items.Count-1 do
begin
p:=Treeview1.Items.Data;
dispose(p);
Treeview1.Items.Data:=nil;
end;
Adoquery1.Close;
Close;
end;


如果这样改了还有问题那就是你在其他有方用到了Treeview1的节点的Data,你可以把For循环移到Form的OnDestroy事件中去试试!如果还不行,那就可能是其他原因,请把代码Email给我,我帮你分析分析.aizb@163.net
 
treeviewitem在内存中本身就是一个指针,它的释放应该是窗体本身释放时自动操作的呀
我有一个树也是这样的, 但窗体释放时我没有写特殊的释放指针代码,结果并没有出错呀.

与你唯一不同的是:

Adoquery1.First;
While Not Adoquery1.Eof Do
Begin
new(p);
p^.CardType:=Adoquery1.Fieldvalues['CardType'];
p^.Name:=Adoquery1.Fieldvalues['Name'];
TreeView1.Items.AddObject(nil,p^.Name,p);

Adoquery1.Next;
End;
ADOquery1.Close;//我的加了这一句
 
"谁来看看这个‘杂碎’"

只有新疆人才这么说?
 

Similar threads

I
回复
0
查看
598
import
I
I
回复
0
查看
643
import
I
I
回复
0
查看
428
import
I
I
回复
0
查看
650
import
I
I
回复
0
查看
504
import
I
顶部