Arrays Delphi如何释放动态实例化按钮数组?
释放在frmTransaction.Show上创建的按钮数组时出现问题 当from再次显示时,我收到一个无效的操作错误。 当我用不同的用户运行程序时,它会说已经有同名的项目: 这段代码是我程序中唯一可以释放内存的部分Arrays Delphi如何释放动态实例化按钮数组?,arrays,delphi,button,memory-management,Arrays,Delphi,Button,Memory Management,释放在frmTransaction.Show上创建的按钮数组时出现问题 当from再次显示时,我收到一个无效的操作错误。 当我用不同的用户运行程序时,它会说已经有同名的项目: 这段代码是我程序中唯一可以释放内存的部分 SetLength(btnSale,iTrans); for i := 1 to iTrans do begin readln(tPos,sPos); iPos := Pos(';',sPos); //Gets positio
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;
SetLength函数设置动态数组的长度。high成员将是MyArray[LengthMyArray-1],在代码的第二部分中使用high函数。您的代码正在寻址成员btnSale[i],因此它没有对成员0执行任何操作,而是正在寻址位于高边界上方的成员btnSale[LengthbtnSale]
试着用这个
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;
您已删除程序的关键部分。我们看不到代码的第一部分在哪里。没有必要给这些控件命名。我们不知道不同的用户意味着什么。请减少此项并制作MCVE。是否确实要创建/释放FormShow/FormHide中的按钮?为什么不在FormCreate中创建它们?这样,您就不需要显式地释放它们,因为您在创建它们时定义了所有者。您是否尝试过在FormHide中设置断点来检查释放是否确实发生过?另外,什么时候调用创建?我们无法从您的代码中看到这一点,请显示所有相关代码。我注意到您为按钮提供了父级:bgxSales。如果在FormHidei中尝试释放按钮时,此父项在某个地方被释放,可能会产生此错误。如果您是与所有者一起创建按钮,则TButton.CreategbxSales只需释放gbxSales,您就可以开始了。它会自动摧毁你的按钮哇,太明显了,真不敢相信我没有看到这个。。。。因此,对于i:=1的iTrans do,btnSale[i]:=TButton.CreategbxSales;当我到达iTrans时应该引发一个索引越界异常,不是吗?@Fantagirocco,似乎是这样,但我们看不到代码调用的上下文。如果它在里面的某个地方,除了结束,怎么办?无论如何。索引设置不正确,我们必须先更正此错误,然后才能继续处理其他错误。我同意您的回答和评论,但我想知道为什么应用程序以前没有引发异常:您的try-catch也可能是正确的block@J... 释放的默认关闭仍然是合理的。我就是这样滚的。但是默认为调试构建关闭是愚蠢的。一方面,Emba表示,他们希望引入ARC,让新手编程更容易。但是,它们不会启用范围检查、溢出检查或键入地址。