class function CDataOperate.GetDataSet(Const SqlStr:String;out DataSet:TDataSet):boolean;
var
  QryData:TAdoQuery;
begin
  result:=nil;
  QryData:=TAdoQuery.Create(nil);
  QryData.Close;
  QryData.ConnectionString:=ConnStr;
  QryData.SQL.Clear;
  QryData.SQL.Text:=SqlStr;
  try
  begin
    QryData.Open;
    DataSet:=QryData;
    result:=true;
    QryData.Free; //这句是关键的,如果注释这一句,内存不会报错
  end;
  except on E:Exception do
  begin
    QryData.Free;
    result:=false;
    ShowMessage(E.Message);
  end;
end;
end;
//a function//Apply code
procedure TFormMain.Button1Click(Sender: TObject);
var
  qry:TDataSet;
begin
  SqlStr:='select sysdate from dual';
  if CDataOperate.GetDataSet(SqlStr,qry) then
  begin
    Showmessage('Yeah,Succesfull');
    DataSource1.DataSet:=qry;
    DbGrid1.DataSource:=DataSource1;
    qry.Free;
  end
  else
  begin
    Showmessage('Oh,shit,failure');
  end;
end;
在函数里面已经采用了Out向外传参的方式,再释放QryData的时候,就会导致内存错误?
有什么办法?

解决方案 »

  1.   

    DataSet只是个引用而已,你释放之后引用就无效了,函数外面自然无法引用
    把你的GetDataSet改为FillDataSet就行了,看改过的函数名应该知道怎么做了吧
      

  2.   

    access violation at address 0047C59F in module ***.exe .Read of address 00000028
    就是因为被Free掉,所以才会这样出错,但是怎样做得更好呢?
      

  3.   

    直接用传递的 DATASET来操作不是更方便.而且你这样,导致了DATASET指向了一个释放了的不可用指针.肯定会出错的.
      

  4.   

     result:=nil;返回值不是boolean型吗?
      

  5.   

    把主程序里面的DATASET作参数传进去,再把GetDataSet取得的数据FILL到DATASET,GetDataSet函数不要释放DATASET,主程序就能调用了