Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 2019
-
27 janv. 2009 à 19:37
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 2022
-
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
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;
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
Bacterius
Messages postés3792Date d'inscriptionsamedi 22 décembre 2007StatutMembreDernière intervention 3 juin 201610 27 janv. 2009 à 19:50
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 ?
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 )
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 27 janv. 2009 à 20:59
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
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 27 janv. 2009 à 21:21
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...
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 .
Caribensila
Messages postés2527Date d'inscriptionjeudi 15 janvier 2004StatutMembreDernière intervention16 octobre 201918 28 janv. 2009 à 01:57
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 !