拉撒路的访问违规行为

时间:2014-05-02 00:43:47

标签: pointers freepascal lazarus

我一直在做我的大学项目,我偶然发现了无法解决的问题。 在声明变量(指向TButton的指针)后,我无法使用它。我将复制部分代码以帮助显示问题。

所以在实施之前我有

private
    prevButton : ^TButton;

之后我使用OnClick程序和我的按钮

procedure TForm2.MissingButtonClick(Sender : TObject);
var
    b : TButton;
begin
     b := Sender as TButton;
     prevButton := @b;
     showmessage(prevButton^.Caption);
end; 

标题显示没问题。但是当我使用OnClick程序并尝试更改标签标题时,我会遇到访问冲突。

procedure TForm2.LabelClick(Sender : TObject);
var
    l : TLabel;
begin
     l := Sender as TLabel;
     if prevButton = nil then
        showmessage('nil');
     if prevButton <> nil then begin
        showmessage(prevButton^.Caption);
        l.Caption := (prevButton^.Caption);
        prevButton^.OnClick := @AlreadyClicked;
        prevButton^.Free;
        prevButton^ := nil;
        prevButton := nil;
        refreshLabels(words);
     end;
end;

所以这就是问题,为什么我可以在这个程序中使用我的变量,如果我可以在其他程序中更早地使用它而没有问题。

干杯。

1 个答案:

答案 0 :(得分:0)

您的代码在多个地方存在严重缺陷。

首先,初始声明不正确。 TButton类型的变量已经是指针,因此您不必取消引用它:

private
  prevButton: TButton;

在分配或使用它时,您也不必取消引用它:

procedure TForm2.MissingButtonClick(Sender : TObject);
begin
  prevButton := TButton(Sender);
  showmessage(prevButton.Caption);
end; 

我不确定您的LabelClick活动正在尝试完成什么。如果您释放prevButton,则还会使您指向的原始按钮无效。换句话说,如果您分配了prevButton := Button1;,然后又分配了prevButton.Free;,那么您还可以释放Button1,而我并不认为这是您的意图。您可以安全地将nil分配给prevButton,但也不要将其释放:

prevButton := nil;   // No longer points to existing object instance

如果您想更改现有按钮的OnClick,请不要跳过所有这些环节:

// Assign this to the button's OnClick in the Object Inspector
procedure TForm1.Button1FirstClick(Sender: TObject);
begin
  ShowMessage('First time I was clicked');
  Button1.OnClick := @Button1AfterClicked;
end;

// Create these two in the code editor, and declare it in the 
// form declaration, but don't assign it to an event of the button
// in the Object Inspector
procedure TForm1.Button1AfterClick(Sender: TObject);
begin
  ShowMessage('Second time clicked');
  Button1.OnClick := @Button1MoreClicks;
end;

procedure TForm1.Button1MoreClicks(Sender: TObject);
begin
  ShowMessage('Third and later clicks');
end;