【容器+结构体】注意事项1
//这里的List是一种容器,是一种泛指,可以是List、StringList、ThreadList、ObjectList等!
//现以List为例做一个例子!
unit StudentExample; interface uses Classes,SysUtils,Dialogs; type //定义结构体及其指针,定义指针目的在于把指针放到List容器中 PStudent = ^TStudent; TStudent = packed record Name: PChar;//这里以指针数据为例(简单数据类型太简单,没什么可注意的) Age: Integer; end; TStudentExample=class private FStudentList:TList ;//容器List procedure ClearStuInfo; public constructor Create; destructor destroy;override; procedure AddStuInfo;//生成结构体,并把指针添加信息至List procedure DisplayStuInfo;//显示List内结构体 end; implementation constructor TStudentExample.Create; begin inherited; FStudentList:=TList.Create; end; destructor TStudentExample.destroy; begin ClearStuInfo; FStudentList.free; inherited; end; procedure TStudentExample.AddStuInfo; var PStu:PStudent; FIndex:Integer; begin for FIndex:=0 to 3 do begin New(PStu); GetMem(PStu^.Name,10);//对结构体内的PChar指针进行分配内存 StrPCopy(PStu^.Name,'Lp'+IntToStr(FIndex)); PStu^.Age:=FIndex; FStudentList.Add(PStu); end; end; procedure TStudentExample.ClearStuInfo; var FIndex:Integer; begin for FIndex:=0 to 3 do begin //注意1: //用GetMem进行申请的内存须用FreeMem来释放! //如果不释放这里会出现内存泄露 FreeMem(PStudent(FStudentList.Items[FIndex]).Name); //注意2: //用New申请的内存须用Dispose来释放 Dispose(PStudent(FStudentList.Items[FIndex])); end; end; procedure TStudentExample.DisplayStuInfo; var FIndex:Integer; begin for FIndex:=0 to 3 do begin ShowMessage('name='+PStudent(FStudentList.Items[FIndex]).Name); ShowMessage('age='+Inttostr(PStudent(FStudentList.Items[FIndex]).age)) ; end; end; end.
【容器+结构体】注意事项2
用无类型指针释放
unit Unit2; interface uses Classes,SysUtils,Dialogs; type PStudent = ^TStudent; TStudent = packed record Name: String;//这里以String为例,众所周知,String为一个指针,不用GetMem来显式申请内存,并且其内有计数,由RTL来管理生命周期 Age: Integer; end; TStudentExample=class private FStudentList:TList ; procedure ClearStuInfo; public constructor Create; destructor destroy;override; procedure AddStuInfo; procedure DisplayStuInfo; end; implementation constructor TStudentExample.Create; begin inherited; FStudentList:=TList.Create; end; destructor TStudentExample.destroy; begin ClearStuInfo; FStudentList.free; inherited; end; procedure TStudentExample.AddStuInfo; var PStu:PStudent; FIndex:Integer; begin for FIndex:=0 to 3 do begin New(PStu); PStu^.Name:='lp'+Inttostr(FIndex); PStu^.Age:=FIndex; FStudentList.Add(PStu); end; end; procedure TStudentExample.ClearStuInfo; var FIndex:Integer; begin for FIndex:=0 to 3 do begin //Dispose(FStudentList.Items[FIndex]); //这时如果用无类型指针释放FStudentList内的结构体时,不能对其内的String进行释放,也就是无法对String进行引用减1,从而导致在释放结构体时释放不完整!下面的代码是正确的!对于为什么会这样,大家看一下__Finalize(p, typeinfo)的VCL代码 Dispose(PStudent(FStudentList.Items[FIndex])); end; end; procedure TStudentExample.DisplayStuInfo; var FIndex:Integer; begin for FIndex:=0 to 3 do begin ShowMessage('name='+PStudent(FStudentList.Items[FIndex]).Name); ShowMessage('age='+Inttostr(PStudent(FStudentList.Items[FIndex]).age)) ; end; end; end.