我的代码如下:type
TLeafNode =record
VOPC: String;
COED: array[1..4] of string;
VOPA: array of array of array of array of real;
end;
TPLeafNode = ^TLeafNode;procedure TForm1.Button1Click(Sender: TObject);
var
Lp: TPLeafNode;
i: Integer;
begin
for i:=1 to 1000 do
begin
LP:=AllocMem(Sizeof(TLeafNode));
SetLength(LP.VOPA,1000,1000,1000,1000);
LP.VOPA:=nil;
FreeMem(LP,Sizeof(TLeafNode));
end;
end;结果记录的内存没有释放掉,经过大约几百次循环,最后内存溢出。
请问怎么样才能把我申请的记录和记录中的那个四维动态数组释放掉?
TLeafNode =record
VOPC: String;
COED: array[1..4] of string;
VOPA: array of array of array of array of real;
end;
TPLeafNode = ^TLeafNode;procedure TForm1.Button1Click(Sender: TObject);
var
Lp: TPLeafNode;
i: Integer;
begin
for i:=1 to 1000 do
begin
LP:=AllocMem(Sizeof(TLeafNode));
SetLength(LP.VOPA,1000,1000,1000,1000);
LP.VOPA:=nil;
FreeMem(LP,Sizeof(TLeafNode));
end;
end;结果记录的内存没有释放掉,经过大约几百次循环,最后内存溢出。
请问怎么样才能把我申请的记录和记录中的那个四维动态数组释放掉?
var
Lp: TPLeafNode;
i: Integer;
begin
for i:=1 to 1000 do
begin
LP:=AllocMem(Sizeof(TLeafNode));
SetLength(LP.VOPA,1000,1000,1000,1000);
FreeMem(LP.VOPA);
end;
end;
var
Lp: TPLeafNode;
i: Integer;
begin
for i:=1 to 1000 do
begin
LP:=AllocMem(Sizeof(TLeafNode));
SetLength(LP.VOPA,1000,1000,1000,1000);
FreeMem(LP.VOPA);
FreeMem(Lp);
end;
end;
可以说,肯定是那个四维数组没有释放,我试了一下,使用FreeMem(LP.VOPA)也不能解决内存增长问题。不知道怎么回事。
LP.VOPA := nil;试试?
我有一个指针数组 VHPA:Array of TPLeafNode;
因为需要不停的创建TleafNode类型的记录来存放数据库中的值(维数比较大),所以在使用完记录后需要释放,我使用上面我所说的释放方法,结果没运行几次循环就溢出了。
你用这个试试呢?
Finalize(Lp.VOPA);
new dispose
for (i=0;i<1000;i++)
{
lp = NULL;
lp = (PTLeafNode)malloc(sizeof(double)*1000*1000*1000*1000);
if (lp ==NULL )//系统无法为lp分配内存,太大了,953674兆,不予理睬,直接break
{
MessageBox (NULL, TEXT ("Out of memory"), TEXT("123"), MB_ICONERROR) ;
break;
}
free(lp);
}另外,我转换的原理应该没错吧?
FreeMem(Lp);
LP.VOPA:=nil;这句后面让LP.VOPA:=nil;所以没有释放。
把LP:=AllocMem(Sizeof(TLeafNode));放到循环外面
分配了i个(1000,1000,1000,1000)大小的空间。
var
i,j: integer;
RA: Array of Integer;
LP: TPLeafNode;
Str1,Str2: String;
begin
{结果记录初始化}
SetLength(RA,4);
LP:=TPLeafNode(NodeCreate(Sizeof(TLeafNode)));
RA[0]:=0; RA[1]:=0; RA[2]:=0; RA[3]:=0; for i:=Low(TPSetNode(T.MCP).Data) to High(TPSetNode(T.MCP).Data) do
begin
if (RA[0]<TPSetNode(T.MCP).Data[i][0]) then RA[0]:=TPSetNode(T.MCP).Data[i][0];
if (RA[1]<TPSetNode(T.MCP).Data[i][1]) then RA[1]:=TPSetNode(T.MCP).Data[i][1];
if (RA[2]<TPSetNode(T.MCP).Data[i][2]) then RA[2]:=TPSetNode(T.MCP).Data[i][2];
if (RA[3]<TPSetNode(T.MCP).Data[i][3]) then RA[3]:=TPSetNode(T.MCP).Data[i][3];
end; SetLength(LP.VOPA,RA[0]+1,RA[1]+1,RA[2]+1,RA[3]+1); for i:=Low(TPSetNode(T.MCP).CS) to High(TPSetNode(T.MCP).CS) do
LP.COED[i]:=TPSetNode(T.MCP).CS[i]; if (T.OS='S') then //累加或连乘运算
begin
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]+
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]; //显示检查
{ for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
begin
for j:=Low(TPSetNode(T.PLSet).Data[i]) to High(TPSetNode(T.PLSet).Data[i]) do
begin
Str1:=Str1+' '+FloatToStr(TPSetNode(T.MCP).Data[i][j]);
Str2:=Str2+' '+FloatToStr(TPSetNode(T.PLSet).Data[i][j]);
end;
FrmCaculation.Memo1.Lines.Add(' ');
FrmCaculation.Memo1.Lines.Add('MCP: '+Str1);
FrmCaculation.Memo1.Lines.Add('MLP: '+Str2);
Str1:=''; Str2:='';
end; }
end
else if (T.OS='P') then
begin
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]*
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]];
end
else if (T.RCP=nil)and(T.PRValue=nil)and(T.PRSet=nil) then //单目运算
begin
if T.OS='sin' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
sin(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
if T.OS='cos' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
cos(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
if T.OS='tan' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
Tan(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]);
if T.OS='exp' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
exp(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]); end
begin
if T.OS='+' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]+
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]; if T.OS='-' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]-
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]; if T.OS='*' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]*
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]; if T.OS='/' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]/
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]; if T.OS='^' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=
POWER(TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]],
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]);
if T.OS='>' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]>
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0; if T.OS='<' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]<
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0; if T.OS='=' then
for i:=Low(TPSetNode(T.PLSet).Data) to High(TPSetNode(T.PLSet).Data) do
if (TPLeafNode(T.PLValue).VOPA[TPSetNode(T.PLSet).Data[i][0]][TPSetNode(T.PLSet).Data[i][1]][TPSetNode(T.PLSet).Data[i][2]][TPSetNode(T.PLSet).Data[i][3]]=
TPLeafNode(T.PRValue).VOPA[TPSetNode(T.PRSet).Data[i][0]][TPSetNode(T.PRSet).Data[i][1]][TPSetNode(T.PRSet).Data[i][2]][TPSetNode(T.PRSet).Data[i][3]]) then
LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=1
else LP.VOPA[TPSetNode(T.MCP).Data[i][0]][TPSetNode(T.MCP).Data[i][1]][TPSetNode(T.MCP).Data[i][2]][TPSetNode(T.MCP).Data[i][3]]:=0; end;
Result:=LP;
end;
二叉树的后序遍历function BinaryTreePostOrderTraverse(T:TPTwigNode): Pointer;
var S: Array of stackelement;
Top: Integer;
Root: TPTwigNode;
begin
SetLength(S,255);
Top:=0;
Root:=T; //保存根指针
while (T<>nil) or (top<>0) do
begin
while T<>nil do
begin
INC(top,1);
S[top].T:=T;
S[top].tag:=0;
T:=T.LCP;
end;
while (top<>0) and (s[top].tag=1) do
begin
if S[top].T.FP<>nil then
if S[top].T.FPF='Left' then
begin
if TPTwigNode(S[top].T.FP).PLValue<>nil then NodeFree(TPLeafNode(TPTwigNode(S[top].T.FP).PLValue));//如果存在旧结果则释放
TPTwigNode(S[top].T.FP).PLValue:=Caculation(S[top].T);
end
else if S[top].T.FPF='Right' then
begin
if TPTwigNode(S[top].T.FP).PRValue<>nil then NodeFree(TPLeafNode(TPTwigNode(S[top].T.FP).PRValue));//如果存在旧结果则释放
TPTwigNode(S[top].T.FP).PRValue:=Caculation(S[top].T);
end
else showmessage('二叉树生成:头指针标志赋值错误');
Dec(top,1);
end;
if top<>0 then
begin
S[top].tag:=1;
T:=S[top].T.RCP;
end;
end;
S:=nil;
Result:= Caculation(Root);
end;实验函数:
procedure TFrmCaculation.Button18Click(Sender: TObject);
var i, j:Integer;
RP: TPLeafNode;
begin
j:=StrToInt(Edit2.Text);
for i:=0 to j do
begin
RP:=TPLeafNode(BinaryTreePostOrderTraverse(P));
RP.VOPA:=nil;
FreeMem(RP);
end;
end;实验:重复调用二叉树计算,看内存变化。
然后在Edit2中填入5000,点Button18,内存每秒长大约16K,我实在找不出问题,只好求求大家看看。
1,record的结构不是很良好,一般情况下,record的结构尽量使用基本类型,如果存在array of array of....等,最好将array of 再用一个结构封装
2,对应String的释放问题。delphi的string的管理其实是一个指针。这里我建议将array[1..4] of string; 换成:array [0..3] of pchar,而后动态的给pchar分配内存。这样可以确定保证没有内存泄漏。
3,对于复杂的record,可以使用类来代替,这样,对于内存的管理可以统一操作
4,使用boundercheck for delphi可以检查到你的内存什么地方没有处理:)
我使的是MemProof,来监视内存。