Recent

Author Topic: (Solved) Problem with TStrHolder  (Read 6267 times)

ezlage

  • Guest
(Solved) Problem with TStrHolder
« on: August 13, 2012, 08:53:31 pm »
Friends,

When I call the PegaStr() function, I receive the error in attachment.
Someone knows how to solve this?

Thanks.

Code: [Select]
type
  TBase=(bin,oct,dec,duo,hex,abc,afn);
  TCase=(mai,min,nat);

  TCentral = class(TDataModule)
    SthCofre0: TStrHolder;
    SthCofre1: TStrHolder;
    SthCofre2: TStrHolder;
    function PegaStr(const c:integer; const p:integer):string;
  end;

var
  Central: TCentral;

function GeraChave(const b:TBase; const c:TCase; t:SmallInt):string;

implementation

function TCentral.PegaStr(const c:integer; const p:integer):string;
begin
  case c of
    0: result:=SthCofre0.Strings.Strings[p];
    1: result:=SthCofre1.Strings.Strings[p];
    2: result:=SthCofre2.Strings.Strings[p];
  end;
end;

function GeraChave(const b:TBase; const c:TCase; t:SmallInt):string;
var
  e: string;
  x: integer;
  s: string='';
begin
  with Central do begin
    case b of
      bin: e:=PegaStr(1,0);
      oct: e:=PegaStr(1,1);
      dec: e:=PegaStr(1,2);
      duo: e:=PegaStr(1,3);
      hex: e:=PegaStr(1,4);
      abc: e:=PegaStr(1,5);
      afn: e:=PegaStr(1,6);
    end;
  end;
  case t of
    0: t:=SortTChave;
    else if (not t>0)
        then t:=1;
  end;
  for x:=0 to t-1 do begin
    s:=s+e[random(Length(e))+1];
  end;
  case c of
    mai: s:=UpperCase(s);
    min: s:=LowerCase(s);
  end;
  result:=s;
end;
« Last Edit: August 14, 2012, 11:16:05 pm by ezlage »

Knipfty

  • Full Member
  • ***
  • Posts: 232
Re: Problem with TStrHolder
« Reply #1 on: August 13, 2012, 09:14:48 pm »
Hi ez,

I don't see where you've instatiated SthCofre0, SthCofre1, and/or SthCofre2.  I've gotten that error before by failing to do just that.

Knipfty
64-bit Lazarus 2.2.0 FPC 3.2.2, 64-bit Win 11

ezlage

  • Guest
Re: Problem with TStrHolder
« Reply #2 on: August 13, 2012, 09:36:39 pm »
Knipfty, thanks!

But I'm not getting with the procedure "Create".

How you did?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TStrHolder
« Reply #3 on: August 13, 2012, 09:46:37 pm »
As Knipfty indicated SIGSEV faults most often arise because a class is nil, and you are trying to access its (nonexistent) properties.
You'll have to post the entire unit for us to help you further. For instance, without a uses statement a stranger like me cannot tell what your TStrHolder class is.

ezlage

  • Guest
Re: Problem with TStrHolder
« Reply #4 on: August 13, 2012, 10:00:15 pm »
Howardpc, see:

First call:
Code: [Select]
procedure TFrmAcesso.AIProtect;
begin
  randomize;
  codabert:=GeraChave(afn,nat,random(6)+7);
  Caption:=' ('+codabert+') '+Caption;
end;

undcentral.pas
Code: [Select]
unit undcentral;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, ExtCtrls, Forms, undtipos, StrHolder, StrUtils, Dialogs;

type

  { TCentral }

  TCentral = class(TDataModule)
    SthCofre0: TStrHolder;
    SthCofre1: TStrHolder;
    SthCofre2: TStrHolder;
    function PegaStr(const c:integer; const p:integer):string;
    {...}
  protected
    {...}
  end;

const
  {...}

var
  Central: TCentral;
  {...}

function GeraChave(const b:TBase; const c:TCase; t:SmallInt):string;

implementation

uses
  undacesso, undprincipal;

{function SortTChave:integer;
begin
  result:=random((sec_tmaxc-sec_tminc))+sec_tminc+1;
end;}

function GeraChave(const b:TBase; const c:TCase; t:SmallInt):string; //Gera uma string aleatória com a base, tamanho e case informados
var
  e: string; //Caracteres da base escolhida
  x: integer; //Marcador de posição para estrutura de repetição, tamanho da chave
  s: string=''; //Saída antes de ser tratada
begin
  with Central do begin
    case b of
      bin: e:=PegaStr(1,0);
      oct: e:=PegaStr(1,1);
      dec: e:=PegaStr(1,2);
      duo: e:=PegaStr(1,3);
      hex: e:=PegaStr(1,4);
      abc: e:=PegaStr(1,5);
      afn: e:=PegaStr(1,6);
    end;
  end;
  case t of
    0: t:=SortTChave;
    else if (not t>0)
        then t:=1;
  end;
  for x:=0 to t-1 do begin
    s:=s+e[random(Length(e))+1];
  end;
  case c of
    mai: s:=UpperCase(s);
    min: s:=LowerCase(s);
  end;
  result:=s;
end;

function TCentral.PegaStr(const c:integer; const p:integer):string;
begin
//  result:=GeraChave(afn,nat,0);
  case c of
    0: result:=SthCofre0.Strings.Strings[p];
    1: result:=SthCofre1.Strings.Strings[p];
    2: result:=SthCofre2.Strings.Strings[p];
  end;
end;

{...}

{$R *.lfm}

end.

undtipos.pas
Code: [Select]
unit undtipos;

{$mode objfpc}{$H+}

interface

uses
  Classes, dbf, FileUtil, SysUtils;

type

  TEixo=(ex,ey,ez);
  TBase=(bin,oct,dec,duo,hex,abc,afn);
  {...}
  TCase=(mai,min,nat);

  {...}

implementation

uses
  undcentral;

{...}

end.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TStrHolder
« Reply #5 on: August 14, 2012, 12:06:46 am »
You need to instantiate the three TStrHolder classes you use, otherwise they do not exist, and the TCentral data fields SthCofre0 etc. are simply pointers to nil (nothing). Trying to access the properties of three nothings will unfailingly give you an access violation. I don't understand Spanish, so you code is not readily accessible to me, however at a minimum you need to create the TStrHolders, something like:

Code: [Select]
TCentral = class(TDataModule)
    SthCofre0: TStrHolder;
    SthCofre1: TStrHolder;
    SthCofre2: TStrHolder;
    function PegaStr(const c:integer; const p:integer):string;
    {...}
  protected
    {...}
  public
    constructor Create(aOwner: TComponent); override;
  end;     

implementation

constructor TCentral.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);
  SthCofre0 := TStrHolder.Create(Self);
  SthCofre1 := TStrHolder.Create(Self);
  SthCofre2 := TStrHolder.Create(Self);

  // add required initialization of each SthCofreX here
end;       

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Problem with TStrHolder
« Reply #6 on: August 14, 2012, 07:02:28 am »
Sorry, Ezequiel, I was completely on the wrong track - I assumed you were trying to create TCentral in code.
I realise that you are using rx controls, and have created a datamodule in the IDE.
Your access violation arises either because you are trying to access strings beyond the length of a stringlist, or because you try to access a character beyond the end of a string.
The first error can be caught by adding a 'uses Dialogs;' clause and adapting your PegaStr function as follows:

Code: [Select]
function TCentral.PegaStr(const c: integer; const p: integer): string;
begin
 //  result:=GeraChave(afn,nat,0);
  case c of
    0: if Assigned(SthCofre0.Strings) and (SthCofre0.Strings.Count > p-1) then
        result:=SthCofre0.Strings.Strings[p]
       else ShowMessageFmt('Index %d is  beyond upper range of %d',[p, SthCofre0.Strings.Count]);
    1: if Assigned(SthCofre1.Strings) and (SthCofre1.Strings.Count > p-1) then
        result:=SthCofre1.Strings.Strings[p]
       else ShowMessageFmt('Index %d is  beyond upper range of %d',[p, SthCofre1.Strings.Count]);
    2: if Assigned(SthCofre2.Strings) and (SthCofre2.Strings.Count > p-1) then
        result:=SthCofre2.Strings.Strings[p]
       else ShowMessageFmt('Index %d is  beyond upper range of %d',[p, SthCofre2.Strings.Count]);
  end;
end;     

The second problem can be avoided by altering one line of GeraChave so you don't access the nonexistent character beyond the end of the string:
Code: [Select]
begin
  with Central do begin
    case b of
      bin: e:=PegaStr(1,0);
      oct: e:=PegaStr(1,1);
      dec: e:=PegaStr(1,2);
      duo: e:=PegaStr(1,3);
      hex: e:=PegaStr(1,4);
      abc: e:=PegaStr(1,5);
      afn: e:=PegaStr(1,6);
    end;
  end;
  case t of
    0: t:=SortTChave;
    else if (not t>0)
        then t:=1;
  end;
  //if (e <> '') then
  for x:=0 to t-1 do begin
    s:=s+e[random(Length(e))]; // e[Length(e) + 1] will cause an access violation
  end;
  case c of
    mai: s:=UpperCase(s);
    min: s:=LowerCase(s);
  end;
  result:=s;
end;                             

ezlage

  • Guest
Re: Problem with TStrHolder
« Reply #7 on: August 14, 2012, 11:11:12 pm »
I tried to change form creation order and it works.
Problem seems to be caused by delayed creation of the datamodule (Central must to be created first).

Thank you very much!

 

TinyPortal © 2005-2018