vaso123
vaso123

Reputation: 12391

SIGSEGV error in lazarus

I hava a form, and on a button click I want to read a file. That is fine, my program does it.

temekek.txt includes string string integer.

Reading of the file is fine.

I want to do some validation, so I want to check how many cities (first string) in the file.

My idea is to collect all unique cities in an array.

When I want to create a dynamic array, I've got an erreor SIGSEGV.

I uninstalled mine 64bit Lazarus, and installed 32bit, the result is the same.

Here is my program:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, strutils;

type

  { TmainForm }

  TmainForm = class(TForm)
    readProcutsBtn: TButton;
    procedure readProcutsBtnClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }

  end;

type
  productFileRow = record
    productCity, productName: string;
    productCount: integer;
  end;

var
  mainForm: TmainForm;
  productFileDataArray: array[1..200] of productFileRow;
  isProductFileValid: boolean;

const
  minCities = 2;

const
  maxCities = 50;

const
  productsFile = 'termek.txt';



implementation

{$R *.lfm}

{ TmainForm }


procedure readProducts;

var
  i: integer;
  productFileIn: TextFile;
  line: string;

begin
  assignFile(productFileIn, productsFile);
  reset(productFileIn);
  i := 0;

  while not EOF(productFileIn) do
  begin
    readLn(productFileIn, line);
    SScanf(Line, '%s %s %d', [@productFileDataArray[i].productCity,
      @productFileDataArray[i].productName, @productFileDataArray[i].productCount]);
    i := i + 1;
  end;
  closefile(productFileIn);

end;

function validateCityCount: boolean;

var
  cities: array of string;
  productFileRowItem: productFileRow;
  i: integer;

begin
  for productFileRowItem in productFileDataArray do
  begin
    i := 0;

    if not (AnsiMatchStr(productFileRowItem.productCity, cities)) then
    begin
      SetLength(cities, i);
      cities[i] := productFileRowItem.productCity;
      i := i + 1; 
    end;

  end;

  validateCityCount := False;
end;

procedure TmainForm.readProcutsBtnClick(Sender: TObject);
begin
  readProducts;
  if not validateCityCount then
  begin
    ShowMessage('Sorry, product file is invalid, too much or too less cities');
    Exit;
  end;
  ShowMessage('Products readed form `' + productsFile + '`');

end;

end.

My program dies at this row:

cities[i] := productFileRowItem.productCity;

Upvotes: 0

Views: 973

Answers (1)

LU RD
LU RD

Reputation: 34899

You set SetLength(cities,i) with a one off length. First time i is zero, which means an empty array. Next line tries to access first element in the array, which causes the crash.

To correct:

SetLength(cities,i+1);

Upvotes: 3

Related Questions