String in PRecord und heaptrc verursacht SIGSEV

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
PascalDragon
Beiträge: 955
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: String in PRecord und heaptrc verursacht SIGSEV

Beitrag von PascalDragon »

Mathias hat geschrieben: Sa 11. Jan 2025, 16:51
Und FillChar ist kein venünftiges Substitut für Initialize, denn Managed types müssen nicht unbedingt mit 0 Initialisiert werden.
Wen ich das so lese, kann man den Bezeichner noch anders befüllen, als nur mit $00 ?
ZB. Das ein Vector aus 3 single 1,, 0, 1 hat ?
Stichwort Managed Records:

Code: Alles auswählen

program tmngdrec;

{$mode objfpc}
{$modeswitch advancedrecords}

type
  TVector3 = record
    v: array[0..2] of Single;
    class operator Initialize(var aVec: TVector3);
  end;

class operator TVector3.Initialize(var aVec: TVector3);
begin
  aVec.v[0] := 1.0;
  aVec.v[1] := 0.0;
  aVec.v[2] := 1.0;
end;

var
  v: TVector3;
begin
  Writeln(v.v[0], ' ', v.v[1], ' ', v.v[2]);
end.
Mathias hat geschrieben: Sa 11. Jan 2025, 16:51 Da ist mir auch noch etwas aufgefallen, wieso kommt da nicht 3mal 0 raus, sondern die Zufallszahlen ?

Code: Alles auswählen

  procedure Test;
  var
    v: TVec;
  begin
    v := [Random, Random, Random];
    Initialize(v);
    WriteLn(v[0]: 4: 2,'  ', v[1]: 4: 2,'  ', v[2]: 4: 2);
  end;
Initialize initialisiert nur verwaltete Typen, da diese einen korrekten Wert benötigen, damit die Verwaltungsfunktionen keine Fehler erzeugen.

In FPC main sollte man Default() verwenden, da dieses sowohl verwaltete als auch nicht verwaltete Felder auf sinnvolle Werte setzt. In der 3.2 Serie wird der Initialize()-Operator von Managed Records nicht aufgerufen. Solange du also keine managed Records verwendest (also nur Strings und Interfaces), dann heißt die Empfehlung auch Default().
FPC Compiler Entwickler

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: String in PRecord und heaptrc verursacht SIGSEV

Beitrag von Mathias »

Stichwort Managed Records:
Code: Alles auswählen

Code: Alles auswählen

program tmngdrec;

{$mode objfpc}
{$modeswitch advancedrecords}

type
  TVector3 = record
    v: array[0..2] of Single;
    class operator Initialize(var aVec: TVector3);
  end;

class operator TVector3.Initialize(var aVec: TVector3);
begin
  aVec.v[0] := 1.0;
  aVec.v[1] := 0.0;
  aVec.v[2] := 1.0;
end;

var
  v: TVector3;
begin
  Writeln(v.v[0], ' ', v.v[1], ' ', v.v[2]);
end.
Das sieht schon mal recht gut aus, was mich dabei noch stört, das es noch einen record braucht.

Daher habe ich folgendes probiert, aber es gib bei operator ein SyntaxFehler.

Code: Alles auswählen

  {$mode objfpc}
  {$modeswitch advancedrecords}
  {$modeswitch typehelpers}    

type
  TVector3f = array[0..2] of single;

  TVector3fHelper = type Helper for TVector3f
    class operator Initialize(var aVec: TRecVector3);
  end;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Zvoni
Beiträge: 376
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: String in PRecord und heaptrc verursacht SIGSEV

Beitrag von Zvoni »

Mathias hat geschrieben: Di 14. Jan 2025, 08:39 Das sieht schon mal recht gut aus, was mich dabei noch stört, das es noch einen record braucht.

Daher habe ich folgendes probiert, aber es gib bei operator ein SyntaxFehler.

Code: Alles auswählen

  {$mode objfpc}
  {$modeswitch advancedrecords}
  {$modeswitch typehelpers}    

type
  TVector3f = array[0..2] of single;

  TVector3fHelper = type Helper for TVector3f
    class operator Initialize(var aVec: TRecVector3);
  end;  
Wiki/Doku lesen hilft:
https://wiki.freepascal.org/Helper_types#Restrictions
A helper type may not

contain (class) destructors (except in trunk FPC 3.3.1)
contain class constructors (except in trunk FPC 3.3.1)
Wobei ich mir auch nicht sicher bin, ob ich da nen Schmarrn geschrieben habe.
Die "Operators" sind meinem verständnis nach ausschliesslich für Record-Typen.
Da dein Ur-Typ kein Record ist.....

EDIT:
Hab mal rumgespielt

Code: Alles auswählen

program Project1;
{$mode objfpc}
{$modeswitch typehelpers}

type
 TVector3f = array[0..2] of single;

 { TVector3fHelper }

 TVector3fHelper = type Helper for TVector3f
    Constructor Create(aVec: TVector3f);
    Procedure DoPrint;
 end;

{ TVector3fHelper }

constructor TVector3fHelper.Create(aVec: TVector3f);
begin
  Self:=aVec;
end;

procedure TVector3fHelper.DoPrint;
Var i:Integer;
begin
  For i:=Low(Self) To High(Self) Do
  Writeln('Value=',Self[i]);
end;

Var t:TVector3f;
begin
  t[0]:=1.0;
  t[1]:=2.0;
  t[2]:=3.0;
  t.DoPrint;
  Readln;
end.
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Mathias
Beiträge: 6919
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: String in PRecord und heaptrc verursacht SIGSEV

Beitrag von Mathias »

EDIT:
Hab mal rumgespielt
Du initialisierst hier manuell.

Code: Alles auswählen

Var t:TVector3f;
begin
  t[0]:=1.0;
  t[1]:=2.0;
  t[2]:=3.0;
  t.DoPrint;
  Readln;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten