记录的内存释放问题?(解决者赠以高分)

wangjiki1111 2003-10-19 08:38:49
我的代码如下:

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;

结果记录的内存没有释放掉,经过大约几百次循环,最后内存溢出。
请问怎么样才能把我申请的记录和记录中的那个四维动态数组释放掉?
...全文
50 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangjiki1111 2003-10-21
  • 打赏
  • 举报
回复
问题症结已经找到,谢谢各位参与!
hbqinlei 2003-10-20
  • 打赏
  • 举报
回复
study!
fj218 2003-10-20
  • 打赏
  • 举报
回复
GZ
飞翔的老虎 2003-10-20
  • 打赏
  • 举报
回复
个人认为:
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可以检查到你的内存什么地方没有处理:)
wangjiki1111 2003-10-20
  • 打赏
  • 举报
回复

二叉树的后序遍历

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,我实在找不出问题,只好求求大家看看。
wangjiki1111 2003-10-20
  • 打赏
  • 举报
回复
else // 双目运算
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;
wangjiki1111 2003-10-20
  • 打赏
  • 举报
回复
计算函数

function Caculation(T:TPTwigNode): Pointer;
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
gmxlj 2003-10-20
  • 打赏
  • 举报
回复
如果确实想这样做的话:就在每次循环的过程最后,用function ReAllocMem(P:Pointer;CurSize,NewSize:Cardinal):Pointer;来释放堆。
gmxlj 2003-10-20
  • 打赏
  • 举报
回复
还有,你的循环没有意义,因为动态数组的重新定义和I没有关系,你只是在内存中为LP.VOPA
分配了i个(1000,1000,1000,1000)大小的空间。
gmxlj 2003-10-20
  • 打赏
  • 举报
回复
你写的语句有问题:
把LP:=AllocMem(Sizeof(TLeafNode));放到循环外面
zzh54zzh 2003-10-20
  • 打赏
  • 举报
回复
SetLength(LP.VOPA,1000,1000,1000,1000);
LP.VOPA:=nil;

这句后面让LP.VOPA:=nil;所以没有释放。
dickeybird888 2003-10-20
  • 打赏
  • 举报
回复
哈哈
(·¥·)
VisualLion 2003-10-20
  • 打赏
  • 举报
回复
我认为是由于内存的申请和释放在所用时间上或时机上的不对称导致了以前申请的内存没有完全释放掉,新的内存已经开始申请了。
wangjiki1111 2003-10-20
  • 打赏
  • 举报
回复
boundercheck???哪儿下载???
我使的是MemProof,来监视内存。
hatedeadlock 2003-10-20
  • 打赏
  • 举报
回复
FreeMem(LP.VOPA);
FreeMem(Lp);
hatedeadlock 2003-10-20
  • 打赏
  • 举报
回复
……——……
flyinwuhan 2003-10-19
  • 打赏
  • 举报
回复
我用C++试了一下----其实根本没办法试:
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);
}

另外,我转换的原理应该没错吧?
huojiehai 2003-10-19
  • 打赏
  • 举报
回复
我也试图找过答案也找不到,就是觉得这种动态申请和释放内存不安全,后来我改为用tstringlist自己写了个内存表控件,当然也可以用tclientdataset做内存表
huojiehai 2003-10-19
  • 打赏
  • 举报
回复
我以前做项目时也到过,这种不停的申请和释放的内存确实会引起内存的泄漏,我用的是
new dispose
hiflower 2003-10-19
  • 打赏
  • 举报
回复
按理不应该有问题啊
你用这个试试呢?
Finalize(Lp.VOPA);
加载更多回复(10)

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧