动态指针数组该如何进行内存动态分配及内存释放?

risingsoft 2003-04-24 10:27:24
以下是我自己编写的一些代码,在进行动态指针数组释放的时候总是提示错误,请各位大虾给予指正,谢谢!!!
从 标注有这里的这里的这行开始,第一次释放成功,可是进行第2次[1][1]释放就出错

procedure TForm1.aDDnodeClick(Sender: TObject);
const
ID_CLASS =DWORD($80000001);
ID_STUDENT=DWORD($80000002);

type
PBirthDay=^TBirthDay;
TBirthDay=Record
rYear: String[4];
rMonth: String[2];
rDay: String[2];
end;

PStudent=^TStudent;
TStudent=Record
rLevel: DWORD;
rStuID: String[7];
rClass: String[5];
rNumber: String[2];
rName: String[6];
rBirthDay: PBirthDay;
end;

PClass=^TClass;
TClass=Record
rLevel: DWORD;
rClassID: String[5];
rClassName: String[10];
rStuCount: Integer;
rMaster: PStudent;
rStudents: Array of PStudent;
end;

function CopyStu(aSrcStu, aDecStu: PStudent): Integer;
begin
aDecStu.rLevel:=aSrcStu.rLevel;
aDecStu.rStuID:=aSrcStu.rStuID;
aDecStu.rClass:=aSrcStu.rClass;
aDecStu.rNumber:=aSrcStu.rNumber;
aDecStu.rName:=aSrcStu.rName;
aDecStu.rBirthDay.rYear:=aSrcStu.rBirthDay.rYear;
aDecStu.rBirthDay.rMonth:=aSrcStu.rBirthDay.rMonth;
aDecStu.rBirthDay.rDay:=aSrcStu.rBirthDay.rDay;

Result:=0;
end;

function CopyClass(aSrcClass, aDecClass: PClass): Integer;
var
i: integer;
begin
aDecClass.rLevel:=aSrcClass.rLevel;
aDecClass.rClassID:=aSrcClass.rClassID;
aDecClass.rClassName:=aSrcClass.rClassName;
aDecClass.rStuCount:=aSrcClass.rStuCount;
CopyStu(aSrcClass.rMaster, aDecClass.rMaster);
for i:=1 to aSrcClass.rStuCount do
begin
try
CopyStu( PStudent(aSrcClass.rStudents[i]), PStudent(aDecClass.rStudents[i]) );
except
end;
end;

Result:=0;
end;

var
CurNode, ClsNode, StuNode: TTreeNode;

newCls : PClass;
newStu : PStudent;
newClss: array of PClass;
newStus: array of PStudent;
i, j: Integer;
begin
newCls:=AllocMem( SizeOf(TClass) );
newCls.rMaster:=AllocMem( SizeOf(TStudent) );
newCls.rMaster.rBirthDay:=AllocMem( SizeOf(TBirthDay) );
SetLength(newCls.rStudents, 2);
for i:=1 to 2 do
begin
PStudent(newCls.rStudents[i]):=AllocMem( SizeOf(TStudent) );
PStudent(newCls.rStudents[i]).rBirthDay:=AllocMem( SizeOf(TBirthDay) );
end;
SetLength(newClss, 2);
for i:=1 to 2 do
begin
PClass(newClss[i]):=AllocMem( SizeOf(TClass) );
PClass(newClss[i]).rMaster:=AllocMem( SizeOf(TStudent) );
PClass(newClss[i]).rMaster.rBirthDay:=AllocMem( SizeOf(TBirthDay) );
SetLength( PClass(newClss[i]).rStudents, 2 );
for j:=1 to 2 do
begin
PStudent(newClss[i].rStudents[j]):=AllocMem( SizeOf(TStudent) );
PStudent(newClss[i].rStudents[j]).rBirthDay:=AllocMem( SizeOf(TBirthDay) );
end;
end;

newStu:=AllocMem( SizeOf(TStudent) );
newStu.rBirthDay:=AllocMem( SizeOf(TBirthDay) );


newCls.rLevel:=ID_CLASS;
newCls.rClassID:='98853';
newCls.rClassName:='计算机通信';
newCls.rStuCount:=2;

newCls.rMaster.rLevel:=ID_STUDENT;
newCls.rMaster.rStuID:='9885301';
newCls.rMaster.rClass:='98853';
newCls.rMaster.rNumber:='01';
newCls.rMaster.rName:='白玉川';

newCls.rMaster.rBirthDay.rYear:='1980';
newCls.rMaster.rBirthDay.rMonth:='01';
newCls.rMaster.rBirthDay.rDay:='01';

CopyStu( PStudent(newCls.rMaster), PStudent(newStu) );

for i:=1 to 2 do
begin
CopyStu( PStudent(newCls.rMaster), PStudent(newCls.rStudents[i]) );
end;

trvM.Items.Clear;
ClsNode:=trvM.Items.AddChildObjectFirst(nil, newCls.rClassName, newCls);
CurNode:=ClsNode;
StuNode:=trvM.Items.AddChildObject(CurNode, '(vip) - '+newStu.rName, newStu);
CurNode:=StuNode;
for i:=1 to 2 do
begin
StuNode:=trvM.Items.AddChildObject(ClsNode, '( '+PStudent(newCls.rStudents[i]).rNumber+') - '+
PStudent(newCls.rStudents[i]).rName,
PStudent(newCls.rStudents[i]) );
end;
CurNode:=StuNode;

for i:=1 to 2 do
begin
CopyClass( PClass(newCls), PClass(newClss[i]) );
end;

for i:=2 downto 1 do
begin
for j:=2 downto 1 do
begin
FreeMem( PStudent( PClass(newClss[i]).rStudents[j]).rBirthDay);//-这里-//
FreeMem( PStudent( PClass(newClss[i]).rStudents[j]) );
end;
FreeMem( PClass(newClss[i]).rMaster.rBirthDay);
FreeMem( PClass(newClss[i]).rMaster);
FreeMem( PClass(newClss[i]) );
end;

for i:=2 downto 1 do
begin
FreeMem( PStudent(newCls.rStudents[i]).rBirthDay );
FreeMem( PStudent(newCls.rStudents[i]) );
end;
FreeMem(newCls.rMaster.rBirthDay);
FreeMem(newCls.rMaster);
FreeMem(newCls);

FreeMem(newStu.rBirthDay);
FreeMem(newStu);

end;
...全文
192 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
runranrun 2003-04-24
  • 打赏
  • 举报
回复
我看你是把string和char弄混淆了,把record定义里的string[4]之类的东东改成char[4].
string其实也是数组,使用之前要SetLength,你的record里的string没有SetLength
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
所以我要请教高手了 一般人都也没办法解决的 都无法给我个答案!
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
艾,看了都要减寿的啦,
为什么要用Record而不用Object?
rustle 2003-04-24
  • 打赏
  • 举报
回复
性情中人啊...
citytramper 2003-04-24
  • 打赏
  • 举报
回复
呵呵
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
呵呵 吵归吵 不过问题解决了。。。还是感谢你 缺钙 不过不是你教会我解决的 我解决是突然想到了Low 和High取数组下界上界的函数 这也是看别人的代码想起来的。
然后看了你评论 算你说对了 其实是数组越界造成的。我觉得应该客观面对问题,你只有这点是对的 其他的 我不想多说了 呵呵
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
缺钙?????
我看不是缺钙 是缺IO。缺扁吧

---
靠,开始咬人了,我闪~~
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
1.最主要的,数组是0开始的,你却弄成1开始,错的不成样子:这个不用你教,只是我不想使用第0数组。

---
可不是你想不想的问题哦,你设置了从0开始,却不想使用? 晕~ 一开始的非法地址错就是数组越界造成的。

2.喜欢用AllocMem?用New和Dispose安全且方便:你白痴啊,AllocMem可以提供最优化的分配内存方式。

---------
呵呵

3.rBirthDay等为什么不直接用TBirthDay,却用PBirthDay,看不出有任何的好处:使用TBirthDay,那就太简单了,那我还用问别人吗?
-----
是阿是阿,忘了你是来玩难度的。要是Record再复杂一些,不知道你要写多少个AllocMem。

4.PBirthDay.Year := 'XXXX',严格的来说,应该写成PBirthDay^.Year := 'XXXX':不懂别装懂,我的直接引用不可以吗,只是你的是间接引用。
--
这个到真是不大懂,汗!查查Help先...


5.你把PXXX等赋给TTreeNode.Data,却马上释放了它们:我的程序还没完成,我的思想是建立一个动态节点,保存当前节点的信息。你了解什么?

-----
的确不了解,不知道谁看了你的代码就能马上了解 呵呵

6.建议学习对象编程,尝试将各个Record改成从TObject继承的子类,Array等改成TList:我可以说你面对问题的态度 心态不好 有问题就要解决 你逃避问题 看你就没真本事 光知道指手画脚 你算什么东西?
--------
原来这叫逃避问题,呵呵
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
这个是我的TreeView的OnChange事件代码 你还有什么要说吗 ?缺IO同志!

procedure TForm1.trvMChange(Sender: TObject; Node: TTreeNode);
const
ID_CLASS =DWORD($80000001);
ID_STUDENT=DWORD($80000002);

type
PBirthDay=^TBirthDay;
TBirthDay=Record
rYear: String[4];
rMonth: String[2];
rDay: String[2];
end;

PStudent=^TStudent;
TStudent=Record
rLevel: DWORD;
rStuID: String[7];
rClass: String[5];
rNumber: String[2];
rName: String[6];
rBirthDay: PBirthDay;
end;

PClass=^TClass;
TClass=Record
rLevel: DWORD;
rClassID: String[5];
rClassName: String[10];
rStuCount: Integer;
rMaster: PStudent;
rStudents: Array of PStudent;
end;
var
ClsNode, StuNode: TTreeNode;
sClsNode: PClass;
sStuNode: PStudent;
begin
try
sClsNode:=PClass(Node.Data);
sStuNode:=PStudent(Node.Data);
except
end;
if DWORD(sClsNode.rLevel)=ID_CLASS then
begin
ShowMessage(sClsNode.rClassID+' - '+sClsNode.rClassName);
end;
if DWORD(sStuNode.rLevel)=ID_STUDENT then
begin
ShowMessage(sStuNode.rStuID+' - '+sStuNode.rName);
end;
end;

对了 对于那位说我把STRING和CHAR混淆了 其实不是的 我试过把字符串长度限定去掉 一样不出什么问题,只是浪费内存罢了 嘿嘿~
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
缺钙?????
我看不是缺钙 是缺IO。缺扁吧
yoisyois 2003-04-24
  • 打赏
  • 举报
回复
呵呵,我来听课呢~~~~
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
至于为什么我没有增加释放内存代码 我想大家都会明白的 不明白?=自己学去

对于那个缺钙 我对你毫不客气地说 你是个垃圾 对于你的问题 我逐个给你回答

代码中的错误:
1.最主要的,数组是0开始的,你却弄成1开始,错的不成样子:这个不用你教,只是我不想使用第0数组。
2.喜欢用AllocMem?用New和Dispose安全且方便:你白痴啊,AllocMem可以提供最优化的分配内存方式。
3.rBirthDay等为什么不直接用TBirthDay,却用PBirthDay,看不出有任何的好处:使用TBirthDay,那就太简单了,那我还用问别人吗?
4.PBirthDay.Year := 'XXXX',严格的来说,应该写成PBirthDay^.Year := 'XXXX':不懂别装懂,我的直接引用不可以吗,只是你的是间接引用。
5.你把PXXX等赋给TTreeNode.Data,却马上释放了它们:我的程序还没完成,我的思想是建立一个动态节点,保存当前节点的信息。你了解什么?
6.建议学习对象编程,尝试将各个Record改成从TObject继承的子类,Array等改成TList:我可以说你面对问题的态度 心态不好 有问题就要解决 你逃避问题 看你就没真本事 光知道指手画脚 你算什么东西?
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
麻烦你把我提的1-5点一条一条回答一下,6也就算了,知道你不懂。
rustle 2003-04-24
  • 打赏
  • 举报
回复
嘿嘿

risingsoft(一苇渡江) ,你的问题就出在程序过度复杂

不影响性能的情况下,指针能不用就不用,尽量不要自己管理内存,尽量使用object

是不是以前用的C?
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
你看看Low(newClss)是多大?
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
代码完成的功能是
1、建立班级指针、学生指针
2、给班级指针赋值 且将班级中的班长赋值给学生指针
3、将班级中的班长赋值给所有的学生数组
4、将班级负值到班级动态指针数组
risingsoft 2003-04-24
  • 打赏
  • 举报
回复
INeedCa(缺钙) 不懂少来这里乱吹牛。我的代码经过修正 绝对可行 你别以为你吹鼻子瞪眼睛能吓坏我!学习学习吧

procedure TForm1.aDDnodeClick(Sender: TObject);
const
ID_CLASS =DWORD($80000001);
ID_STUDENT=DWORD($80000002);

STUCOUNT=50;
CLSCOUNT=10;

type
PBirthDay=^TBirthDay;
TBirthDay=Record
rYear: String[4];
rMonth: String[2];
rDay: String[2];
end;

PStudent=^TStudent;
TStudent=Record
rLevel: DWORD;
rStuID: String[7];
rClass: String[5];
rNumber: String[2];
rName: String[6];
rBirthDay: PBirthDay;
end;

PClass=^TClass;
TClass=Record
rLevel: DWORD;
rClassID: String[5];
rClassName: String[10];
rStuCount: Integer;
rMaster: PStudent;
rStudents: Array of PStudent;
end;

function CopyStu(aSrcStu, aDecStu: PStudent): Integer;
begin
aDecStu.rLevel:=aSrcStu.rLevel;
aDecStu.rStuID:=aSrcStu.rStuID;
aDecStu.rClass:=aSrcStu.rClass;
aDecStu.rNumber:=aSrcStu.rNumber;
aDecStu.rName:=aSrcStu.rName;
aDecStu.rBirthDay.rYear:=aSrcStu.rBirthDay.rYear;
aDecStu.rBirthDay.rMonth:=aSrcStu.rBirthDay.rMonth;
aDecStu.rBirthDay.rDay:=aSrcStu.rBirthDay.rDay;

Result:=0;
end;

function CopyClass(aSrcClass, aDecClass: PClass): Integer;
var
i: integer;
begin
aDecClass.rLevel:=aSrcClass.rLevel;
aDecClass.rClassID:=aSrcClass.rClassID;
aDecClass.rClassName:=aSrcClass.rClassName;
aDecClass.rStuCount:=aSrcClass.rStuCount;
CopyStu(aSrcClass.rMaster, aDecClass.rMaster);
for i:=Low(aSrcClass.rStudents) to High(aSrcClass.rStudents) do
begin
try
CopyStu( PStudent(aSrcClass.rStudents[i]), PStudent(aDecClass.rStudents[i]) );
except
end;
end;

Result:=0;
end;

var
CurNode, ClsNode, StuNode: TTreeNode;

newCls : PClass;
newStu : PStudent;
newClss: array of PClass;
newStus: array of PStudent;
i, j: Integer;
begin
trvM.Items.Clear;

newStu:=AllocMem( SizeOf(TStudent) );
newStu.rBirthDay:=AllocMem( SizeOf(TBirthDay) );

newCls:=AllocMem( SizeOf(TClass) );
newCls.rMaster:=AllocMem( SizeOf(TStudent) );
newCls.rMaster.rBirthDay:=AllocMem( SizeOf(TBirthDay) );
SetLength(newCls.rStudents, STUCOUNT);
for i:=Low(newCls.rStudents) to High(newCls.rStudents) do
begin
newCls.rStudents[i]:=AllocMem( SizeOf(TStudent) );
newCls.rStudents[i].rBirthDay:=AllocMem( SizeOf(TBirthDay) );
end;
SetLength(newClss, CLSCOUNT);
for i:=Low(newClss) to High(newClss) do
begin
newClss[i]:=AllocMem( SizeOf(TClass) );
newClss[i].rMaster:=AllocMem( SizeOf(TStudent) );
newClss[i].rMaster.rBirthDay:=AllocMem( SizeOf(TBirthDay) );
SetLength( newClss[i].rStudents, STUCOUNT );
for j:=Low(newClss[i].rStudents) to High(newClss[i].rStudents) do
begin
newClss[i].rStudents[j]:=AllocMem( SizeOf(TStudent) );
newClss[i].rStudents[j].rBirthDay:=AllocMem( SizeOf(TBirthDay) );
end;
end;

newCls.rLevel:=ID_CLASS;
newCls.rClassID:='98853';
newCls.rClassName:='计算机通信';
newCls.rStuCount:=STUCOUNT;

newCls.rMaster.rLevel:=ID_STUDENT;
newCls.rMaster.rStuID:='9885301';
newCls.rMaster.rClass:='98853';
newCls.rMaster.rNumber:='01';
newCls.rMaster.rName:='白玉川';

newCls.rMaster.rBirthDay.rYear:='1980';
newCls.rMaster.rBirthDay.rMonth:='01';
newCls.rMaster.rBirthDay.rDay:='01';

CopyStu( newCls.rMaster, newStu );

for i:=Low(newCls.rStudents) to High(newCls.rStudents) do
begin
CopyStu( newCls.rMaster, newCls.rStudents[i] );
end;

for i:=Low(newClss) to High(newClss) do
begin
CopyClass( newCls, newClss[i] );
ClsNode:=trvM.Items.AddChildObjectFirst(nil, newClss[i].rClassName, newClss[i]);
CurNode:=ClsNode;
StuNode:=trvM.Items.AddChildObject(ClsNode, '(vip) - '+newClss[i].rMaster.rName, newClss[i].rMaster);
CurNode:=StuNode;
for j:=Low(newClss[i].rStudents) to High(newClss[i].rStudents) do
begin
StuNode:=trvM.Items.AddChildObject(ClsNode, '( '+newClss[i].rStudents[j].rNumber+') - '+
newClss[i].rStudents[j].rName,
newClss[i].rStudents[j] );
CurNode:=StuNode;
end;
end;
end;
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
今天被老板训了一通,找个毛毛头出出气~ 呵呵~~
INeedCa 2003-04-24
  • 打赏
  • 举报
回复
runranrun(醉里挑灯看剑) ,
String[4]是限制该String为4个字符。

risingsoft(一苇渡江) ,
说实话,一般人是怎么也不能写出这么一堆垃圾的。
你是不是大一,正在学Pascal?
代码中的错误:
1.最主要的,数组是0开始的,你却弄成1开始,错的不成样子。
2.喜欢用AllocMem?用New和Dispose安全且方便。
3.rBirthDay等为什么不直接用TBirthDay,却用PBirthDay,看不出有任何的好处。
4.PBirthDay.Year := 'XXXX',严格的来说,应该写成PBirthDay^.Year := 'XXXX'
5.你把PXXX等赋给TTreeNode.Data,却马上释放了它们。
6.建议学习对象编程,尝试将各个Record改成从TObject继承的子类,Array等改成TList。

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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