user2073973
user2073973

Reputation: 584

Keep getting access violation when trying to access array

I'm rather new to delphi, and I keep getting access violations when I try to access my array "nieuwButtons". Does anyone have any idea what I'm doing wrong?

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.

Upvotes: 2

Views: 958

Answers (1)

David Heffernan
David Heffernan

Reputation: 612954

The only way for that line of code to raise an exception is if the instance of TGeneral is not valid.

The error will be found in the code that instantiates the class. Common forms of this error are:

  1. Forgetting to instantiate the object at all.
  2. Instantiating the object incorrectly by calling the constructor on the uninitialized instance rather than the type.

To illustrate the latter fault, it looks like this:

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

But the correct way is like this:

General := TGeneral.Create;

Upvotes: 5

Related Questions