Libérer un tableau dynamique de Tstrings à 2 dimensions [Résolu]

Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 27 janv. 2009 à 19:37 - Dernière réponse : f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention
- 28 janv. 2009 à 13:52
Bonjour,




J'ai besoin d'une structure de données un peu particulière : un tableau dynamique à 2 dimensions de TStringList. Mais je me demande comment libérer tout ça?
Ce tableau n'est pas rectangulaire, donc pour le déclarer, je fais comme ça :



var TestArray : array of array of  TStrings;
      i, j : Integer;



begin
  {Je dimensionne le 1er tableau :}
  SetLength(TestArray,3,0);
  {Je dimensionne les cellules :}
  SetLength(TestArray[0],1);
  SetLength(TestArray[1],2);
  SetLength(TestArray[2],1);
  {Je remplis le tableau :}
  TestArray[0,0] := TStringList.Create;
  TestArray[1,0] := TStringList.Create;
  TestArray[1,1] := TStringList.Create;
  TestArray[2,0] := TStringList.Create;
  {Ici, j'utilise mon tableau. Par exemple :}
  TestArray[0,0].Add('Test 1');
  TestArray[1,0].Add('Test 2');

  ...




  {Libération des TStringList :}

  for i := 0 to Length(TestArray)-1 do begin
    for j := 0 to Length(TestArray[i])-1 do begin
      TestArray[i,j].Free; // Je libère les TStringList.
    end;
  end;



    {Libération du tableau :}
  Finalize(TestArray); // <- Est-ce bien suffisant???



Voila. Je me demande s'il ne faudrait pas libérer tous les tableaux de chaque cellule?
Merci pour vos lumières.
Cari
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 28 janv. 2009 à 13:52
3
Merci
faut que je pense a approfondire mes exemples :

Type
  TMachin = pointer;
  TMyArrays = array of array of TMachin

var
  MyArrays = TMyArrays;

memoire occupée par MyArrays :

4 bytes

allocation :

SetLength(MyArrays, 2);

memoire occupée :

(2 * 4) bytes

allocation :

SetLength(MyArray[0], 10);
SetLength(MyArray[1], 5);

memoire occupée :

68 bytes

allocation :

for N := 0 to 9 do
  case N of
    0..4 : begin
             New(MyArrays[0,N]);
             New(MyArrays[1,N]);
           end;
    5..9 :  New(MyArrays[0,N];
  end;

memoire occupée :

128 bytes

désalocation :

for N := 9 downto 0 do
  case N of
    0..4 : begin
             Dispose(MyArrays[1,N]);
             Dispose(MyArrays[0,N]);
           end;
    5..9 : Dispose(MyArrays[0,N]);
  end;
SetLength(MyArrays[1], 0);
SetLength(MyArrays[0], 0);
SetLength(MyArrays, 0);

autre possibilité :

type
  TMyArrays = array of array of TMachin;
  pMyArrays = ^TMyArrays;

var
  ptr : pMyArrays;

allocation :
  New(ptr);
  SetLength(ptr^, 2);
  SetLength(ptr^[0], 10);
  SetLength(ptr^[1], 5);

désalocation :
  SetLength(ptr^[0], 0);
  SetLength(ptr^[1], 0);
  SetLength(ptr^, 0);
  Dispose(ptr);

a savoir aussi que toute variable, constante font au minimum 5 bytes :

[pointeur 4 byte] [type char 1 bytes]

exemple :

var
  MonInt : integer;
  MonString : string;
  MonPointeur : ^byte;

memoire occupée par MonInt = 2*4 bytes
memoire occupée par MonString = (2*4)+1 bytes en UTF8 et (2*4)+2 bytes en UTF16
memoire occupée par MonPointeur non alloué (new) = 2*4 bytes
memoire occupée par MonPointeur alloué  (new) = (2*4)+1 bytes
memoire occupée par MonPointeur assignée sur var existante = 2*4 bytes

Merci f0xi 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de f0xi
Bacterius 3869 Messages postés samedi 22 décembre 2007Date d'inscription 3 juin 2016 Dernière intervention - 27 janv. 2009 à 19:50
0
Merci
Les tableaux dynamiques n'ont pas besoin d'être libérés.

Extrait de l'aide Delphi :

"Les références aux tableaux dynamiques sont comptées et ces tableaux se libèrent automatiquement quand il ne font plus l'objet d'aucune référence."

Il n'y a pas besoin de libérer un tableau dynamique, il s'auto-libère.
Au pire, un Finalize doit être suffisant :

Extrait de l'aide de Delphi (Finalize) :

"Les tableaux dynamiques ne peuvent jamais être désalloués à l'aide de la procédure Dispose, mais vous pouvez les libérer en les transmettant à Finalize."

Mais il est également indiqué que (ça peut peut-être t'aider) : "Dans les cas où plusieurs variables sont désallouées dans un bloc de mémoire contiguë tel qu'un tableau de chaînes alloué dynamiquement, le paramètre additionnel Count peut être spécifié afin de finaliser toutes les variables en une seule opération."

En tout cas moi je n'ai jamais libéré mes tableaux dynamiques conformément à l'aide Delphi - après, ma mémoire vive est une déchetterie peut-être à cause de ça ?

Cordialement, Bacterius !
Commenter la réponse de Bacterius
Utilisateur anonyme - 27 janv. 2009 à 19:56
0
Merci
Salut,

Je comprend pas trop ta question : tu as un seul tableau qui contient différentes cellules. A chaque cellule est rattachée une StringList. Donc

1)Etape 1 : initialisation du tableau //Initialize
2)Etape 2 : dimensionnement du tableau //SetLength
3)Etape 3 : Création de la StringList de chaque cellule  // TStringList.Create
4)Etape 4 :Utilisation des StringList //Add
5)Etaoe 5 : Destruction des StringList // Free
6)Etape 6 : Finalisation du tableau // Finalize

Je vois pas trop ce que l'on peut faire de plus

Mais te connaissant, j'ai du louper un épisode : M'sieur si vous plait, possible de rentrer dans votre vortex cyto-neuronal pour connaitre votre pensée ? (Je te connais mon grand : ta question cache autre chose . M'sieur Cari nous avons les moyens de vous faire parler )
Commenter la réponse de Utilisateur anonyme
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 27 janv. 2009 à 20:18
0
Merci
@Bacterius

En fait, j'ai toujours eu un doute avec ces foutus tableaux dynamiques!

Extrait de l'Aide :
«Pour libérer un tableau dynamique, affectez nil à une variable qui référence le tableau ou transmettez la variable à Finalize»

@Francky  
Regarde bien la déclaration :



array of array of  TStrings;


En fait, c'est un tableau à 1 dimension dont chaque cellule contient un tableau de TStrings.
Ou alors, j'ai encore compris queud' 
Commenter la réponse de Caribensila
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 27 janv. 2009 à 20:59
0
Merci
re@Francky
Je cite M. Beaulieu :

« Avec les tableaux dynamiques multidimentionnels, on est plus proche de ceci :

array[0..2] of array[0..1] of TStrings;

que de cela :

array[0..2, 0..1] of TStrings; »

D'où mon doute...


[mailto:re@Bacterius
re@Bacterius
]


1) Il est possible que les tableaux dynamiques soient désalloués sur le destroy... Mais en attendant, tu te trimballes tes tableaux jusque la fin de l'application. D'où l'intérêt de pouvoir les libérer à la main... 
C'est peut-être une explication au manque de clarté de l'aide...

2) «Dans les cas où plusieurs variables sont désallouées dans un bloc de mémoire contiguë ...»

        - Et à qui je dois demander si c'est le cas ou pas?  lolll
Commenter la réponse de Caribensila
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 27 janv. 2009 à 21:21
0
Merci
Finalement, je vais faire comme ça, c'est plus sûr :

{Libération des TStringList :}
  for i := 0 to Length(TestArray)-1 do begin
    for j := 0 to Length(TestArray[i])-1 do begin
      TestArray[i,j].Free; // Je libère les TStringList.
    end;
  end;




  {Libération des tableaux}

 
for i := 0 to Length(TestArray)-1 do begin
    Finalize(TestArray[i]);
  end;
  Finalize(TestArray);

En tout cas ça passe! Et comme en plus je suis dans une de mes classes, je préfère ne pas prendre de risque...

Merci pour vos réponses, les gars!
Commenter la réponse de Caribensila
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 27 janv. 2009 à 22:46
0
Merci
avec les tableaux dynamique :

type
  TMyArray = array of TMachin;

var MyArray : TMyArray;

memoire occupée :

4 octet

reservation de memoire :

SetLength(MyArray, X);

memoire occupée :

4 + (X * Taille de TMachin)

liberation de la memoire :

SetLength(MyArray, 0);

memoire occupée :

4 octet

Commenter la réponse de f0xi
Utilisateur anonyme - 27 janv. 2009 à 23:39
0
Merci
MonTableau : array[0..2] of array[0..1] of TMachin;

: Pourtant on utilise bien l'expression de tableau multidimentionnel et non de tableau de tableau. Si Beaulieu a raison cela implique que quelque soit le TMachin il faut libérer tout les sous tableaux et non juste MonTableau. Donc ta question dépasse le cadre du TStringList : Voila une question intéressente. Je savais que cela cachait autre chose .
Commenter la réponse de Utilisateur anonyme
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 28 janv. 2009 à 01:57
0
Merci
Bein oui... Les TStringList, on sait bien qu'il faut les libérer.

Mais un tableau dynamique n'est pas comparable à un tableau statique. Ils sont liés à la notion de pointeurs. D'où la taille de 4 octets quand on les déclare (taille d'un pointeur) comme le montre très bien f0xi.

Mais quid d'un tableau de tableaux?
Je pense qu'il faut faire comme j'ai montré et ne pas compter sur l'auto-libération. D'ailleurs je me suis tj demandé qui était le owner d'un tableau (l'application?).

Je pense que l'expression de tableau multidimentionnel quand il s'agit d'un tableau dynamique est une façon de cacher son reel fonctionnement pour le confort du programmeur. Comme souvent, Delphi nous cache l'utilisation des pointeurs. 
C'est sans doute plus confortable, mais il faut quand même en avoir conscience.
C'est pas parce que ça s'utilise de ma même façon que c'est kif-kif !

Enfin, c'est ce que je pense pour le moment...  :)
Commenter la réponse de Caribensila

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.