Delphi Dyncamically создал пункты всплывающего меню - недопустимая операция указателя / нарушение прав доступа
У меня проблема с сообщением об ошибке "Недопустимая операция с плавающей точкой". Всплывающее меню является элементом управления временем разработки и называется NavPop
, У него нет назначенных пунктов меню. Это назначено как popupmenu для Panel1
,
Затем я динамически создаю пункты меню из списка и назначаю заголовок и события щелчка. Все работает на 100% с точки зрения того, что я пытаюсь достичь. Т.е. это работает.
Только когда я закрою программу, я получу
Недопустимая операция с плавающей точкой
или иным образом:
Адрес нарушения доступа 000007355. Чтение адреса 0000007355.
Обратите внимание, что все работает отлично, за исключением того, что ошибка при закрытии программы. Буду признателен за любую помощь.
// I declare the Array of TMenuItems
private
{ Private declarations }
ItemArray : array of TMenuItem;
...
procedure TMainForm.Button1Click(Sender: TObject);
begin
CreateNavPop;
end;
// Create the menu items from listbox(Navlist) items and Link them
// to events on a navigation bar.
procedure TMainForm.CreateNavPop;
var
I: Integer;
NavIndex: Integer;
begin
SetLength(ItemArray, NavList.Items.Count);
NavIndex:=0;
For I:=0 to NavList.Items.Count-1 do
begin
NavIndex:=NavBar1.Items.ItemByCaption(NavList.Items.Strings[i]).Index;
ItemArray[i]:=TMenuItem.create(Nil);
ItemArray[i].Caption:=NavList.Items.Strings[i];
ItemArray[i].OnClick:=NavBar1.Items.Items[Navindex].OnClick;
NavPop.Items.Add(ItemArray[i]);
end;
end;
// Call the Items free on program close
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeItems(ItemArray);
end;
// Free Dynamically created Menu Items on Form Close
procedure TMainForm.FreeItems(MItems : array of TMenuItem);
var
cnt : integer;
begin
for cnt := High(MItems) downto Low(MItems) do
begin
MItems[cnt].Free;
MItems[cnt] := nil;
end;
end;
1 ответ
Это происходит потому, что TPopupMenu уже освобождает элементы, и вы освобождаете его снова.
Этот код вызывает "Недопустимая операция с указателем":
procedure TForm1.FormCreate(Sender: TObject);
var
I: Integer;
begin
for I := 0 to 3 do
PopupMenu1.Items.Add(TMenuItem.Create(nil));
end;
destructor TForm1.Destroy;
var
I: Integer;
begin
for I := 3 downto 0 do
PopupMenu1.Items.Free;
inherited;
end;
Свойство Items является экземпляром TMenuItem, и если вы посмотрите на его деструктор, оно уже освободит все добавленные вами элементы.
destructor TMenuItem.Destroy;
begin
...
while Count > 0 do Items[0].Free;
...
Короче говоря, вам не нужно делать это снова в методе FreeItems.
Я проверил с ReportMemoryLeaksOnShutdown:= True и утечки памяти не происходит.