1 procedure Form1.TestClick(Sender: TObject);
2 var
3 TestBtn1,BtnTemp:TButton;
4 begin
5
6 {第一步:创建一个Button,令指针TestBtn1指向这个在堆中开辟的内存区。}
7 ////////////////////////////////////////////////////////////////////////////
8
9 {NOTE:必须指定name,后面FindComponent就是通过name来找控件的,TestBtn1不是button的name}
10 TestBtn1:=TButton.Create(panel); //让panel做此button的owner
11 with TestBtn1 do
12 begin
13 Caption:='hello'; //设置Button显示文本
14 name:= 'Button1_test';
15 left:=16;
16 top:=16;
17 width:=60;
18 parent:=panel; //让panel1做此Button的parent
19 end;
20
21
22 {第二步:制造内存泄漏,同时保存栈中原指针以作补救}
23 ////////////////////////////////////////////////////////////////////////////
24
25 {保存原指针,注意此处控件名区分大小写,请务必和name属性保持完全一致}
26 btnTemp:=TButton(panel.FindComponent('Button1_test'));
27
28 TestBtn1:=TButton.Create(panel);
29 {TestBtn1指向地址更改,从指向caption为hello的caption转为指向caption为Button2的button,
30 第一个button的指针丢失 }
31 with TestBtn1 do
32 begin
33 Caption:='Button2';
34 left:=16+70;
35 top:=16;
36 width:=60;
37 parent:=panel;
38 end;
39
40 btnTemp.Caption:='world';
41 BtnTemp.Hint:='这是提示';
42 FreeAndNil(panel); //虽然发生内存泄漏,owner还是会负责回收,两个button和一个panel都消失
43 ShowMessage('name:'+btnTemp.name); //name被清空
44 ShowMessage(BtnTemp.Hint);
45 try
46 if btnTemp.Caption='world' then //caption 仍为world,很奇怪
47 begin
48 ShowMessage('OK');
49 btntemp.Caption:='hello world'; //这是非法的,button已经回收了,会造成错误
50 end
51 else
52 begin
53 ShowMessage('crush');
54 end;
55 except
56 ShowMessage('opps!Invalid pointer.');
57 end;
58 end;