各位好:
   我做了一个小的彩票分析工具,其中有一些计算字段,需要用循环来获取这些值。但是一运行就会报错“stack overflow”,程序如下:请各位帮忙看看,多谢!
procedure TForm4.Query1CalcFields(DataSet: TDataSet);
var
  i,j,k,m : integer;
begin
  //从最后一条开始统计间隔期数
   Query1.Last;
 for i := Query1.RecordCount downto 1  do
  begin
    //获取当前记录的开奖结果
    arrValue[0] := Query1.Fields[0].AsInteger;
    arrValue[1] := Query1.Fields[1].AsInteger;
    arrValue[2] := Query1.Fields[2].AsInteger;
    arrValue[3] := Query1.Fields[3].AsInteger;
    arrValue[4] := Query1.Fields[4].AsInteger;
    //从上一期开始查找匹配的开奖数字
    for k := Query1.RecordCount -1 downto 1 do
    begin
      Query1.Prior;
      arrPrior[0] := Query1.Fields[0].AsInteger;
      arrPrior[1] := Query1.Fields[1].AsInteger;
      arrPrior[2] := Query1.Fields[2].AsInteger;
      arrPrior[3] := Query1.Fields[3].AsInteger;
      arrPrior[4] := Query1.Fields[4].AsInteger;
      //获取遗漏值,然后判断所有的遗漏值是否获得,如果已经获得,则退出
      for j:=0 to 4 do
      begin
        for m :=0 to 4 do
        begin
          if arrValue[j]=arrPrior[m] then
          begin
            Query1.Fields[7+j].AsInteger := i - k;
            break;
          end;
        end;
      end;
      if ((Query1.Fields[7].AsInteger <>0) and  (Query1.Fields[8].AsInteger <>0) and (Query1.Fields[9].AsInteger <>0) and
         (Query1.Fields[10].AsInteger <>0) and   (Query1.Fields[11].AsInteger <>0)) or Query1.Bof then
      break;
    end;
    Query1.Prior;
  end;
end;

解决方案 »

  1.   

    可以用编译指令$M(有两个参数)
    不过我看你还是改成非递归吧
    自己用一个stack来记参数
    运行速度也会快一点点
      

  2.   

    timgreen(tim):我写程序不行,给我点提示吧,多谢。
      

  3.   

    OnCalcField的时候不要改变其它字段的值,你一改动就会进入无限递归,多大的stack都没用
      

  4.   

    alphax(多喝了三五杯):我在onCalcField里边赋值的都是赋予计算字段的,那些值只有在循环的过程中计算才能得来。不知道有没有好的办法。
      

  5.   

    我从没在OnCalcField中移动过记录,不知道会怎样,但是你的移动也有问题,先是last,导致OnCalcField触发,然后,OnCalaField又导致Query1.Prior;
    Prior又导致OnCalcField,OnCalcField又导致Last,如此递归可能是这样
      

  6.   

    alphax(多喝了三五杯):多谢。
    不知道如何改,因为我只有不停的移动记录才能算出我需要的结果。
      

  7.   

    没有搞清楚你统计的算法是怎样的,我一般对付这样的问题,都是另外创建一个数据集副本来处理,如果数据不是很多,而且只有prior这样的简单的移动操作,用简单的ClientDataSet就可以了