2011-10-24 54 views
2

D2010,Win7 64bit。 你好,德爾福 - 如何從TDataSet釋放內存?

我有一個buttonClick事件需要處理在另一個例程中打開的TDataSet ... GetDBGenericData。

函數GetDBGenericData返回一個TDataSet。這個例程基本上需要一個tQuery組件,設置它的SQL屬性並打開它。然後它將TDataSet返回到我的按鈕點擊。

procedure TForm1.Button2Click(Sender: TObject); 
var 
DS : TDataSet; 
begin 

DS := TDataSet.Create(nil); 
DS := GetDBGenericData(dbSOURCE, 'LIST_ALL_SCHEMAS', []); 

while Not DS.EOF do 
    begin 
    ShowMessage(DS.FieldByName('USERNAME').AsString); 
    DS.Next; 
    end; 

DS.Close; 
DS.Free; 

我的問題是 - 理解DS。 我在這個例程中創建它。我將它「分配給」指向組件的TDataSet。如果我不釋放它,我有一個內存泄漏(由EurekaLog報告)。 如果我釋放它,我下次運行這個例程時會得到一個AV。 (特別是在GetDBGenericData例程中)。我正在發生的事情是,DS正在被分配給(而不是複製)到正在返回的TDataSet,所以實際上,我在這個例程中解放了DS,並且GetDBGenericData中的tQuery我做了一個免費的。

如何「斷開」鏈接,然後刪除與我只動態創建的內存相關聯的內存。

感謝, GS

回答

4

如果您DS變量被分配另一個TDataSet通過GetDBGenericData,你既不應該CreateFree它。你只是用它來指代現有的數據集。

procedure TForm1.Button2Click(Sender: TObject); 
var 
    DS : TDataSet; 
    UserNameField: TField; // Minor change for efficiency 
begin 
    DS := GetDBGenericData(dbSOURCE, 'LIST_ALL_SCHEMAS', []); 

    // Call FieldByName only once; no need to create or 
    // free this either. 
    UserNameField := DS.FieldByName('USERNAME'); 

    while not DS.Eof do 
    begin 
    ShowMessage(UserNameField.AsString); 
    DS.Next; 
    end; 

    // I'd probably remove the `Close` unless the function call 
    // above specifically opened it before returning it. 
    DS.Close; 
end; 
+0

就是這樣......謝謝。 – user1009073