Dynamische Array erzeugt in const ein Speicher Leak

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
PascalDragon
Beiträge: 963
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: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von PascalDragon »

Mathias hat geschrieben: So 2. Apr 2023, 08:49 Dieses MiniProgram erzeugt ein Speicher Leak.
Bitte melde einen Bug. Der Compiler fügt das Array wohl nicht zum globalen Finalizer hinzu.
six1 hat geschrieben: So 2. Apr 2023, 11:44 für mich verhält sich dieses dynamische Array wie eine Variable, ohne dass diese beim Beenden der Funktion zerstört wird.

Code: Alles auswählen

const
  ar: array of byte = nil;
begin
  SetLength(ar, Length(ar) + 1);
  ar[high(ar)]:=$A5;
  showmessage(inttostr(Length(ar)));
  SetLength(ar, 0);
end; 
komplett sinnbefreit, oder?
Weil es auch eine Variable ist. Eine typisierte Konstante ist letztlich eine Variable, bei welcher der Compiler abhängig von der $WriteableConst-Direktive den Schreibzugriff verweigert oder die Daten eventuell auch in einer ReadOnly Sektion der Binary ablegt (nur auf bestimmten Plattformen wie Windows).

Lokale, typisierte const Bezeichner sind noch dazu letztlich statische Variablen, da dies in TP Zeiten die einzige Möglichkeit war prozedur-/funktionslokale Variablen zu deklarieren. Sowohl Delphi als auch FPC sind hier entsprechend kompatibel dazu. Dieses Verhalten wird sich auch nicht ändern.
Mathias hat geschrieben: So 2. Apr 2023, 18:27
Ja, es klingt komisch, eine Konstante zu ändern,
Dies ist irgendwie auch doof und kann zu Fehlern führen. Somit ist es unter Umständen möglich eine wichtige Konstante zu ändern.

Da habe ich gerade was lustiges gefunden, " unimplemented", was das wieder ist ?

Code: Alles auswählen

const
  CM_BASE                 = $B000;
...
  CM_GOTFOCUS             = CM_BASE + 2 unimplemented;
  CM_LOSTFOCUS            = CM_BASE + 3 unimplemented;
Ein derartig markierter Bezeichner wird bei Verwendung die Warnung „Symbol "xyz" is not implemented” generieren. Dies dient einfach dazu, dass man dem Benutzer kommunizieren kann, dass ein entsprechender Bezeichner auf der jeweiligen Plattform nicht implementiert ist.
FPC Compiler Entwickler

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

Re: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von Mathias »

Ein derartig markierter Bezeichner wird bei Verwendung die Warnung „Symbol "xyz" is not implemented” generieren. Dies dient einfach dazu, dass man dem Benutzer kommunizieren kann, dass ein entsprechender Bezeichner auf der jeweiligen Plattform nicht implementiert ist.
Stimmt, habe es gerade ausprobiert.

Code: Alles auswählen

const
  test1 = 1;
  test2 = 2 unimplemented;

procedure TForm1.Button1Click(Sender: TObject);
begin
  WriteLn(test1);
  WriteLn(test2);  // unit1.pas(38,16) Warning: Symbol "test2" is not implemented
end;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von Mathias »

Bitte melde einen Bug. Der Compiler fügt das Array wohl nicht zum globalen Finalizer hinzu.
Erst morgen, wen ich Zeit habe.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Joh
Lazarusforum e. V.
Beiträge: 288
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von Joh »

fliegermichl hat geschrieben: So 2. Apr 2023, 16:34 Ja und du hast Recht. In lokalen Funktionen deklarierte const Werte sind global.
Einzig der Zugriff darauf ist auf die definierende Prozedur/Funktion beschränkt.
Und da es nur ein Zeiger auf ein dynamisches Array ist, sind die CONST-Werte dann veränderbar. Wenn die C-Welt so funktioniert, dann bin ich froh, nie tiefer in C eingestiegen zu sein.

Aber warum wurd soetwas dann in Pascal übernommen?
Egal, was da geraucht wurde, das Zeug ist nicht gut.
just my two Beer

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von Socke »

Joh hat geschrieben: Mo 3. Apr 2023, 09:47 Und da es nur ein Zeiger auf ein dynamisches Array ist, sind die CONST-Werte dann veränderbar. Wenn die C-Welt so funktioniert, dann bin ich froh, nie tiefer in C eingestiegen zu sein.

Aber warum wurd soetwas dann in Pascal übernommen?
Egal, was da geraucht wurde, das Zeug ist nicht gut.
Nein, es sind "normale" globale Variablen, deren Sichtbarkeit/Zugriff eingeschränkt ist. Mit einem SetLength() wird ggf. der Zeiger verändert.

In C kann man sowohl einen Zeiger als const defnieren als auch dessen Ziel. Damit kann man unterscheiden, ob nur ein Zeiger in einer Prozedur nicht verändert wird, das Objekt/Record dahinter aber schon, oder auch ob die Zieldaten ebenfalls unveränderlich sind.
In Pascal gibt es nichts direkt Vergleichbares; einige Fälle können mit constref abgesichert werden. Es gibt aber syntaktische Unterschiede.

Code: Alles auswählen

program Project1;

{$mode objfpc}{$H+}


type
  TMyRec = record
    i: Integer;
  end;
  PMyRec = ^TMyRec;

  procedure ModifyContent(const prec: PMyRec);
  begin
    prec^.i := 1; // nur der Zeiger ist "const"
  end;

  procedure CantModify(constref rec: TMyRec);
  begin
    rec.i := 1; //  Error: Can't assign values to const variable
  end;

  procedure CantModify2(const rec: TMyRec);
  begin
    rec.i := 1; //  Error: Can't assign values to const variable
  end;

  procedure CantModifyOpenArray(const a: array of TMyRec);
  begin
    // a ist ein Open Array und der ganze Array ist const
    a[0].i := 1; //  Error: Can't assign values to const variable
  end;

type
  TMyRecArray = array of TMyRec;

  procedure ModifyArray(const a: TMyRecArray);
  begin
    // hier bezieht sich das const wieder nur auf den Zeiger des Arrays.
    a[0].i := 1;
  end;

begin
end.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

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

Re: Dynamische Array erzeugt in const ein Speicher Leak

Beitrag von Mathias »

Bitte melde einen Bug. Der Compiler fügt das Array wohl nicht zum globalen Finalizer hinzu.
Gesagt, getan: https://gitlab.com/freepascal.org/fpc/s ... sues/40234
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten