【问题标题】:Keep getting access violation when trying to access array尝试访问数组时不断出现访问冲突
【发布时间】:2017-12-13 18:09:06
【问题描述】:

我对 delphi 比较陌生,当我尝试访问我的数组“nieuwButtons”时,我不断遇到访问冲突。有谁知道我做错了什么?

unit UGeneral;

  interface

  uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
    System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.DBGrids, SMDBGrid,
    KJSMDBGrid, Vcl.ExtCtrls, KJPanel, Vcl.StdCtrls, Vcl.Mask, Vcl.DBCtrls,
    Data.DB;

  type
    TGeneral = class(TObject)

    private
      { Private declarations }

    public
      nieuwButtons: array of TButton;
      nieuwButtonsDataSource: array of TDataSource;

      procedure listEdits(x, y: Integer; owner: TComponent; parent: TWinControl;
        source: TDataSource);
      procedure nieuwClick(Sender: TObject);
      { Public declarations }
    end;

  var
    General: TGeneral;

  implementation

  procedure TGeneral.nieuwClick(Sender: TObject);
  var
    i: Integer;

  begin
    for i := 0 to Length(nieuwButtons) - 1 do
    begin
      if (nieuwButtons[i] = Sender) then
      begin
        nieuwButtonsDataSource[i].DataSet.Insert;
      end;
    end;
  end;

  procedure TGeneral.listEdits(x, y: Integer; owner: TComponent;
    parent: TWinControl; source: TDataSource);
  var
    i: Integer;
    edit: TDBEdit;
    _label: TLabel;
    biggestWidth: Integer;
    button: TButton;
    edits: array of TDBEdit;
    index: Integer;
  begin
    if nieuwButtons <> nil then //I get an access violation here
    begin
      SetLength(General.nieuwButtons, 0);
      SetLength(nieuwButtonsDataSource, 0);
    end;
    index := Length(nieuwButtons);
    SetLength(nieuwButtons, index + 1);
    SetLength(nieuwButtonsDataSource, index + 1);
    button := TButton.Create(owner);
    button.parent := parent;
    button.Top := y;
    button.Left := x;
    button.Caption := 'Nieuw';
    button.OnClick := nieuwClick;

    nieuwButtons[index] := button;
    nieuwButtonsDataSource[index] := source;

    biggestWidth := 0;
    SetLength(edits, source.DataSet.Fields.Count);
    edit := TDBEdit.Create(owner);
    for i := 0 to source.DataSet.Fields.Count - 1 do
    begin
      _label := TLabel.Create(owner);
      _label.parent := parent;
      _label.Caption := source.DataSet.Fields[i].FieldName;
      _label.Top := ((i * 22) + 30 + y); // 22 = standaard(?) hoogte van edittext
      _label.Left := x;

      _label.Show;

      if _label.Width > biggestWidth then
      begin
        biggestWidth := _label.Width;
      end;
    end;
    i := 0;
    for i := 0 to source.DataSet.Fields.Count - 1 do
    begin
      edit := TDBEdit.Create(owner);
      edit.parent := parent;
      edit.DataField := source.DataSet.Fields[i].FieldName;
      edit.DataSource := source;
      edit.Top := ((i * edit.Height) + 30 + y);
      edit.Left := biggestWidth + 30;
      edits[i] := edit;
      edit.Show;
    end;

  end;

end.

【问题讨论】:

  • Assigned 也会引发访问冲突:/
  • 该位置表明Selfnil。显示您如何称呼listEdits
  • General.listEdits(0, 0, Self, KJPanel4, DataModule2.bestemmingSource);
  • @500-InternalServerError 不会是调用方法,而是实例化实例
  • 你应该使用 for i := low(nieuwButtons) to high(nieuwButtons) 而不是 for i := 0 to Length(nieuwButtons) - 1

标签: arrays delphi dynamic access-violation


【解决方案1】:

该行代码引发异常的唯一方法是TGeneral 的实例无效。

在实例化类的代码中会发现错误。此错误的常见形式有:

  1. 根本忘记实例化对象。
  2. 通过调用未初始化实例而不是类型的构造函数来错误地实例化对象。

为了说明后一个故障,它看起来像这样:

var
  General: TGeneral;
....
General.Create; // sometimes this way
General := General.Create; // or sometimes this way

但正确的做法是这样的:

General := TGeneral.Create;

【讨论】:

  • 谢谢!这解决了它。当对象还没有被实例化时,我什至能够在 general 中调用函数,这很奇怪。
  • 这里的General实际上只不过是一个指针。当您编写General.DoSomething(42) 时,实际发生的是方法调用General 的主题作为额外的隐式参数传递。所以真的是TGeneral.DoSomething(General, 42)。现在,如果General 没有被初始化为指向一个有效的实例,调用是可以的,但是当你尝试在对象内部引用Self 时,你通常会遇到运行时错误。
  • 啊,有道理!不知道它是这样工作的,到目前为止只在delphi中编程了2天。我会在一分钟内将您的答案标记为解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多