下面这一个函数,反复执行时,会在Open时发生 out of memory,请问是什么原因?procedure datainit(id:widestring);
var
  TmpQuery:TADOQuery;
begin  TmpQuery:=TADOQuery.Create(nil);
  try
    with TmpQuery do
    begin
      Connection:=dm.conn;
      close;
      sql.clear;
      sql.Append('select * from plan where id='+id);
      try
        open;
      except
      end;
      if not eof then
        begin
          DataPlan.name:=FieldByName('name').AsString;
        end;
    end;
  finally
    TmpQuery.sql.Clear;
    freeandnil(TmpQuery);
  end;
end;用FASTMM看到如下FastMM 已检测到一个错误, 当时正在进行 GetMem 操作. FastMM 检测到对已释放内存块内容的修改. 被修改字节的偏移地址(以及长度): 13(1)上次使用时的内存块大小是: 108当前线程的 ID 是 0x36C8, 导致该错误的堆栈跟踪(返回地址): 
40B3D4 [FastMM4][DebugGetMem]
40B62E [FastMM4][DebugReallocMem]
402F2F [System][@ReallocMem]
424C54 [Classes][TList.SetCapacity]
424ABC [Classes][TList.Grow]
4248CD [Classes][TList.Add]
42DE29 [Classes][TComponent.Insert]
42DE84 [Classes][TComponent.InsertComponent]
42DCCA [Classes][TComponent.Create]
4A3C40 [DB][TField.Create]
4A5517 [DB][TStringField.Create]

解决方案 »

  1.   

    建立后未FREE,这句TmpQuery.sql.Clear;改为TmpQuery.Free;
        freeandnil(TmpQuery);
      

  2.   

    这几句话没看出错误,再检查一下,另外我记得DELPHI 6版本的ADO有个内存泄漏的BUG,确认一下你是否在使用DELPHI 6
      

  3.   

    用了 freeandnil(TmpQuery); 的我用的D7
      

  4.   

    你把下面几句直接放“OPEN();”后面
          if not eof then
            begin
              DataPlan.name:=FieldByName('name').AsString;
            end;
      

  5.   

    不用数据集的话在free以前加入dataset.Close,否则即使你free了但内存并不释放
      

  6.   

    不在使用數據集時請在free前close數據集
      

  7.   

    1.TmpQuery.close;
    TmpQuery.sql.Clear;
    freeandnil(TmpQuery);
    2.TmpQuery经常使用创建一次就好了。
      

  8.   

    查看源码,adoquery.free里有用close,也有清空sql,重复的意义在哪里?destructor TADOQuery.Destroy;
    begin
      inherited Destroy;
      FreeAndNil(FSQL);
    end;destructor TCustomADODataSet.Destroy;
    begin
      Destroying;
      Close;
      SetConnection(nil);
      FreeAndNil(FCommand);
      FreeAndNil(FModifiedFields);
      FreeAndNil(FIndexDefs);
      FreeAndNil(FIndexFields);
      FreeAndNil(FMasterDataLink);
      FreeAndNil(FParams);
      inherited Destroy;
    end;
    而且试过后,无效。那么,反复创建销毁就会导致“到对已释放内存块内容的修改”引发内存溢出错误,这岂不是太不安全了?
      

  9.   

    问题可能是在sql语句里。
    在抛出异常时,show出ID的值,另外你用的是D7,ID为widestring有意义吗?因为sql中的string会为ansistring,加到sql字串中,是否能如预期中正常转换呢?
    若没有必要,声明为string即可
      

  10.   

    是在open时出错的,这时adoquery,有一个分配内存的操作,TStringField.Create改成string,也一样。
      

  11.   

    DataPlan.name:=FieldByName('name').AsString;
    这句注释掉会否仍有问题
    怀疑问题不在这部分
      

  12.   

    有答案了,我在线程中使用了自释放,主线程再次分配内存就会导致上面错误,应该是delphi内存管理的缺陷吧
      

  13.   

    晕。你什么时候提到线程了?凭这个就判断delphi内存管理有缺陷?