|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
Hello,
j'ai trouvé ceci dans un programme : Code :
Ma question en suivant : d'accord, mais alors dans ce cas là, le free sert il à quelque chose ? Je suppose qu'il ne fait que libérer l'espace mémoire alloué localement à Item, mais pas l'espace mémoire de la variable manipulée par l'appelant de la procédure... Mais j'attends les avis des experts. Merci. |
||
|
|
00
|
|
|
#2 |
![]() ![]() Yves LemaireBiologiste ; Progr(amateur) Inscription : mars 2005 Messages : 1 680 ![]() |
Les objets sont passés par adresse [EDIT=mea culpa]
mais il existe depuis Delphi 5 au moins une procedure FreeAndNil qui fait déjà ça et (je crois) ne lève pas d'exception si l'argument n'est pas assigné. [EDIT] l'intérêt de mettre Nil, c'est de ne pas faire planter si on cherche à utiliser cet Item déjà libéré à condition de tester si bien assigné : if Assigned(Item) then Item.Execute;
__________________
Delphi 5 Pro et Code Typhon 2.80 sous Win 7 64 bits - Code Typhon 2.70 / Ubuntu 12.04 64 bits |
|
|
01
|
|
|
#3 | |||
![]() ![]() Inscription : septembre 2008 Messages : 2 856 ![]() |
Citation:
Citation:
Citation:
|
|||
|
|
10
|
|
|
#4 |
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
OK merci à vous.
Donc avec var, ce n'est pas une copie du pointeur mais le pointeur lui même qui est passé, et le nil aurait alors son intérêt. Sans var c'est une copie, mais comme elle pointe sur la même adresse mémoire que l'original, le free va aller libérer cette adresse là, donc on est bon. Pour le freeandnil en effet c'est un programme assez ancien, ça devait pas exister à l'époque de son écriture. Désolé, mais après plus de deux ans sans pratiquer, j'ai un peu perdu certaines bases. |
|
|
00
|
|
|
#5 |
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
Quand même une remarque : en C, par exemple, un paramètre passé par adresse ou bien par valeur, c'est pas exactement comme en Delphi, c'est ça ? Le passage de paramètre Delphi est un peu particulier, non ?
|
|
|
00
|
|
|
#6 | ||
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
J'ai trouvé ceci dans un tuto Delphi du site (celui de Didier Mailliet) :
C. Paramètre donnée variable 1. définition Il s’agit d’un passage de paramètres par valeur. On ne précède le nom du paramètre d’aucun mot (ni var, ni const ni out). Le paramètre peut avoir une valeur avant l’appel, sa valeur peut être modifiée dans la procédure, la modification n’est pas transmise au retour. 2. exemple Code :
Merci. |
||
|
|
00
|
|
|
#7 | ||||
|
Expert Confirmé Sénior
![]() Développeur C++\Delphi Inscription : juillet 2006 Messages : 9 183 ![]() |
ne confond pas un type simple comme Byte et un objet !
Si l'on repart sur ta méthode FreeObject FreeObject appelle la méthode Free, cela invoque du code DE l'objet, il manipule directement SA mémoire C'est le Free qui travaille sur l'objet ! FreeObject effectue une affectation d'une nouvelle valeur mais tout le code est DANS FreeObject et cela ne modifie pas l'objet mais la référence local Item sur celui-ci ! Pense à Self, sur Free ou toute méthode d'objet, il y a un paramètre invisible qui est l'objet lui-même, si l'on traduisait Free objet en un Free procédural : Code :
Code :
__________________
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y ! Attention Troll Méchant ! ![]() "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer ! L'ignorance n'excuse pas la médiocrité ! L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde) Il faut avoir le courage de se tromper et d'apprendre de ses erreurs Halte à la ségrégation des Cinémas, VO sur Paris, VF en Banlieue, Abonnement résilié ! |
||||
|
|
00
|
|
|
#8 | ||
![]() ![]() Inscription : septembre 2008 Messages : 2 856 ![]() |
y.free ne s'applique pas à b, mais à la donnée pointée par b. Nuance
Modifie ton essai ainsi pour t'en convaincre : Code :
|
||
|
|
00
|
|
|
#9 | ||
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
Je pense que je me suis mal fait comprendre.
Pour faire simple voici ce code simplifié : Code :
Car pour moi, si item est une copie de b (ce qui me semble logique) alors le item.free doit s'appliquer à item (la variable locale à la procédure), mais pas à la variable b de l'appelant. Désolé si je vous embête avec tout ça... Si ça vous embête pas alors coooool
|
||
|
|
00
|
|
|
#10 | ||||||
|
Expert Confirmé Sénior
![]() Développeur C++\Delphi Inscription : juillet 2006 Messages : 9 183 ![]() |
Voir le sujet Pointeur sur objet
On a pourtant répondu à cette question, un objet est toujours passé par référence, une sorte de pointeur, cela ne copie pas un objet dans un autre, cela ne fait qu'affecter ce pointeur à un autre variable Pour copier un objet, il existe la méthode Assign, il n'y a pas de mécanisme de copie d'objet comme en C++ le var ou le const en modifications de fonctionns s'applique à la référence sur l'objet (son pointeur) mais pas sur l'instance de l'objet (son contenu) Tu n'as jamais pensé au Sender d'un TNotifyEvent, cela impliquerait que cela copie les objets lors d'un Evènement puis l'objet est passé en paramètre du gestionnaire, imagine une TTreeView rempli, si cela faisait une copie, cela recopierait donc les TTreeNode[s] ? Cela serait tellement pas pratique et contre-performant ! Extrait de l'aide Citation:
Citation:
Note que c'est même plutôt un NilAndFree, qui est plus prudent en multi-thread, on "oublie" la référence avant de libérer, ainsi un Assigned se glissant entre les deux étapes protégera correctement l'accès à l'objet (utile lors de la libération d'une TThreadList ou d'un TCriticalSection, si l'on essaye de l'utiliser pour effectuer un lock alors que l'on est en train de la libérer, l'inverse n'étant pas problématique car le Destroy lock l'objet avant de le libérer) Code :
Code c++ :
void __fastcall FreeAndNil(void *Obj); Code c++ :
__________________
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y ! Attention Troll Méchant ! ![]() "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer ! L'ignorance n'excuse pas la médiocrité ! L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde) Il faut avoir le courage de se tromper et d'apprendre de ses erreurs Halte à la ségrégation des Cinémas, VO sur Paris, VF en Banlieue, Abonnement résilié ! |
||||||
|
|
00
|
|
|
#11 | ||
![]() ![]() Inscription : septembre 2008 Messages : 2 856 ![]() |
Oui, le résultat est le même.
Ce que tu n'as pas encore compris est qu'avant l'appel, il y a déjà deux zones mémoire distincts : le pointeur sur l'objet et l'instance d'objet proprement dite. A l'appel de la procédure, seul le pointeur est copié localement. Même sans penser à l'appel d'une procédure, prenons l'exemple suivant : Code :
Enfin le seul et unique objet est détruit par l'intermédiaire du pointeur "b". "a" n'est pas effacé mais pointe maintenant dans les choux ! (violation d'accès) |
||
|
|
10
|
|
|
#12 |
|
Membre expérimenté
![]() Inscription : janvier 2007 Messages : 996 ![]() |
OK, merci à vous, maintenant c'est plus clair en effet.
|
|
|
00
|
Copyright © 2000-2013 - www.developpez.com