2015-08-26 72 views
2

我有一個問題,解放了我在frmTransaction.Show上創建的按鈕數組 當from from再次顯示時,我得到無效的操作錯誤。 當我使用不同的用戶運行程序,它說有物品已經與該名:) 這段代碼是我的計劃的唯一部分,我的空閒內存德爾福如何釋放動態實例化按鈕的數組?

SetLength(btnSale,iTrans); 
for i := 1 to iTrans do 
begin 
    readln(tPos,sPos); 
    iPos := Pos(';',sPos);       //Gets positions of buttons 
    sTop := Copy(sPos,1,iPos-1); 
    sLeft := Copy(sPos,iPos+1,length(sPos)); 

    btnSale[i] := TButton.Create(gbxSales); 
    with btnSale[i] do 
    begin 
    Parent := gbxSales; 
    name := 'Transaction' + 
       IntToStr(dmdata.tblTransactions['TransactionID']); //Creates buttons that represent Transactions 
    Caption := 'Sale ' + IntToStr(i); 
    Width := 153; 
    Height := 97; 
    Top := StrToInt(sTop); 
    left := strToInt(sleft); 
    show; 
    onClick := ClickSale; 
    end; 
    dmdata.tblTransactions.Next; 
end; 


procedure TfrmTransactions.FormHide(Sender: TObject); 
var 
    i : integer; 
begin 
    for i := low(btnSale) to high(btnSale) do //frees dynamically created objects 
    begin 
    btnSale[i].Free; 
    btnSale[i] := nil; 
    end; 
end; 
+2

您已刪除程序的關鍵部分。我們無法看到第一部分代碼的位置。沒有必要給這些控件名稱。我們不知道「與不同的用戶」是什麼意思。請把它剪下來做一個MCVE。 –

+0

你確定要創建/釋放'FormShow' /'FormHide'中的按鈕嗎?爲什麼不在'FormCreate'中創建它們?那麼你不需要明確地釋放它們,因爲你在創建它時定義了一個所有者。 –

+0

您是否嘗試過在FormHide中設置斷點來檢查釋放是否真的發生了?另外,什麼時候創建的?我們無法從您的代碼中看到,請顯示所有相關代碼。 – GuidoG

回答

4

SetLength功能集的長度動態數組。最高的成員將是MyArray[Length(MyArray)-1](在代碼的第二部分使用高級函數)。您的代碼正在致力於成員btnSale[i],因此它不會對成員#0做任何事情,並且正在處理高於邊界的成員btnSale[Length(btnSale)]

試着用這個。

SetLength(btnSale,iTrans); 
    for i := 0 to iTrans-1 do 
// or this for i := low(btnSale) to high(btnSale) do 
    begin 
    ... 
     btnSale[i] := TButton.Create(gbxSales); 
     with btnSale[i] do 
     ... 

    end; 
+0

哇,很明顯,不能相信我沒有看到這一點。 – GuidoG

+0

...所以用'for i:= 1 to iTrans do ','btnSale [i]:= TButton.Create(gbxSales);'當i達到'iTrans時,應該引發一個* ',不是嗎? – fantaghirocco

+0

@fantaghirocco,看起來如此,但我們沒有看到代碼調用的上下文。如果它在「嘗試除了結束」之外的某個地方呢?任何方式。索引設置不正確,在我們進入其他索引之前糾正這個錯誤是必要的。 –