以下是我自己编写的一些代码,在进行动态指针数组释放的时候总是提示错误,请各位大虾给予指正,谢谢!!!
 从 标注有这里的这里的这行开始,第一次释放成功,可是进行第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;

解决方案 »

  1.   

    艾,看了都要减寿的啦,
    为什么要用Record而不用Object?
      

  2.   

    我看你是把string和char弄混淆了,把record定义里的string[4]之类的东东改成char[4].
    string其实也是数组,使用之前要SetLength,你的record里的string没有SetLength
      

  3.   

    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。
      

  4.   

    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;
      

  5.   

    嘿嘿risingsoft(一苇渡江) ,你的问题就出在程序过度复杂不影响性能的情况下,指针能不用就不用,尽量不要自己管理内存,尽量使用object是不是以前用的C?
      

  6.   

    至于为什么我没有增加释放内存代码 我想大家都会明白的 不明白?=自己学去对于那个缺钙 我对你毫不客气地说 你是个垃圾 对于你的问题 我逐个给你回答代码中的错误:
      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:我可以说你面对问题的态度 心态不好 有问题就要解决 你逃避问题 看你就没真本事 光知道指手画脚 你算什么东西?
      

  7.   

    这个是我的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混淆了 其实不是的 我试过把字符串长度限定去掉 一样不出什么问题,只是浪费内存罢了 嘿嘿~
      

  8.   

    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:我可以说你面对问题的态度 心态不好 有问题就要解决 你逃避问题 看你就没真本事 光知道指手画脚 你算什么东西?
      --------
      原来这叫逃避问题,呵呵
      

  9.   

    呵呵 吵归吵 不过问题解决了还是感谢你 缺钙  不过不是你教会我解决的 我解决是突然想到了Low 和High取数组下界上界的函数 这也是看别人的代码想起来的。
      然后看了你评论 算你说对了 其实是数组越界造成的。我觉得应该客观面对问题,你只有这点是对的 其他的 我不想多说了 呵呵