Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: petrusic - Aprile 15, 2025, 09:58:26 am

Titolo: liberare tutta la memoria impegnata con una chiamata Form.Showmodal
Inserito da: petrusic - Aprile 15, 2025, 09:58:26 am
durante una prova fatta, ho notato che dopo i seguenti comandi:
Codice: [Seleziona]
 Form4.ShowModal;
  Form4.Free;     
il comando Form4.Free   non ha liberato tutta la memoria impegnata dalla chiamata in showmodal, infatti rientrando nella Form4 con una nuova chiamata showmodal ho trovato le variabili globali al suo interno con il contenuto che avevano al momento del rilascio, nonostante il comando Free.

Per me è stata una vera sorpresa. Avevo capito  diversamente.

Ecco la dichiarazione delle variabili che mi aspettavo vuote:
Codice: [Seleziona]
unit Frm4;    // Form4 - Prestiti Momentanei attivi
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls, LCLType,
  UModuloDatiDB, utilmie;
type
  { TForm4 }
  TForm4 = class(TForm)
...bla...bla...bla
var
  Form4: TForm4;
implementation
uses
  FrmMain, Frm2;
{$R *.lfm}
{ TForm4 }
type
...bla...bla...
var
...bla...bla...
  swVistaDettagli: Boolean = False;

  iRgMax: Integer;
...bla...bla...
Io non riesco a vedere altra alternativa se non quella di svuotarle manualmente ad ogni Create della Form4.

Esiste un'altra possibilità automatica?
Titolo: Re:liberare tutta la memoria impegnata con una chiamata Form.Showmodal
Inserito da: DragoRosso - Aprile 15, 2025, 11:39:28 am
Devi prima capire come "funzionano" gli allocamenti della memoria in Pascal (o meglio usando i compilatori FPC e Delphi, che sono paritetici).

E' globale solo ed esclusivamente solo ciò che è definito nella sezione INTERFACE delle varie unità (anche quelli richiamati da altre unità richiamate dalle tue unità ..... ).

Tutto ciò che è riferito globale ha vita e/o visibilità globale per tutta la "durata" della tua applicazione.

In genere, quindi le variabili globali chiamiamole "classiche" sono istanziate e con un valore di default alla partenza del programma direttamente dal compilatore.

I tipi complessi come le classi o i record (sempre globali) invece hanno un percorso un pò diverso, non stò a dilungarmi perchè se no dovrei scrivere un trattato, ma generlamente hanno una parte che viene istanziata a NIL alla partenza o ad altri valori di default come 0, false o ''.
Un' altra parte (le funzioni e le procedure ad esempio) potrebbero essere già assegnate in fase di partenza del programma oppure essere anche queste a NIL, ciò in funzione a come vengono definite.

Non sconvolgerti se in qualche codice vedrai chiamare una procedura di una classe non istanziata, cioè a NIL ... è lecito in certe circostanze.

Oltre a ciò che è globale esiste ciò che non è globale e può essere allocato localmente (stack) o nella memoria HEAP (quella virtuale tanto per intenderci).

Tutto ciò che NON è globale non viene inizializzato (e quindi nemmeno "cancellato") e contiene valori casuali oppure nella maggior parte dei casi gli ultimi valori che quella zona di memoria conteneva.

Nel caso particolare del Pascal, le variabili definite nella sezione Implementation (e solo in testa alla sezione IMPLEMENTATION e non locali ai metodi) hanno durata anche esse fino a chè "esiste" il programma.

Ciò è quello che accade a te ... quello che trovi sono gli ultimi valori delle variabili LOCALI (e non GLOBALI) .... e se per definizione nella IMPLEMENTATION questi dati sono duraturi, nelle locali alle procedure e funzioni è un caso perchè quella memoria può essere sovrascritta in qualsiasi momento.

Quindi come sunto:

- la Form4 non ha legami con le variabili definite nella implementation ne nella interface. Ha solo competenza per ciò che è definito nella propria classe. Questo dovrebbe essere sufficientemente ovvio (a meno che dentro il suo distruttore o il suo creatore non vengano gestite tali variabili).

- La "cancellazione" ossia la loro messa a default può essere effettuata solo a codice, quindi come accennavi dentro il CREATE della Form4 o UNICAMENTE UNA SOLA VOLTA (o PER MEGLIO DIRE DUE VOLTE) con le sezioni INITIALIZATION / FINALIZATION dell'unità.

Tali sezioni tipiche di ogni unità vengono chiamate solo alla partenza e alla chiusura dell'applicazione.

P.S.: DEVI tenere presente che in una unità possono essere definite più classi (e questo avviene normalmente) e quindi non ci può essere un legame diretto e implicito tra le classi e ciò che è definito al di fuori dalle classi.