Page 1 sur 2
Libération de zone mémoire
Publié : sam. 14/mai/2011 9:52
par DarkVader
Bonjour,
Il est spécifié dans la doc PB que toutes les zones mémoires n'ayant pas été libérée par un FreeMemory sont libérées en fin de programme :
cela sous-entend-il que si un pointeur de variable locale est déclaré avec Protected dans une procedureDll
alors la zone mémoire affectée au pointeur dans la procedure sera automatiquement libérée après ProcedureReturn ?
Re: Libération de zone mémoire
Publié : sam. 14/mai/2011 11:12
par case
dans tout les cas la variable est remise a zero en sortant de la procédure.
protected ne conserve pas le contenu de la variable mais permet d'avoir une variable locale avec le même nom qu'une variable globale sans modifier l'une ou l'autre.
Code : Tout sélectionner
Global Z
Global a=50
Procedure blah()
Protected a
a +z ; on ajoute 10 a z a devrait etre 10 20 30 40 50 60 si la variable était conservée
Debug "A protected="+Str(a)
EndProcedure
;
Debug "A global ="+Str(a)
z =10
For k=1 To 10
blah()
Next
Debug "A global ="+Str(a)
Re: Libération de zone mémoire
Publié : sam. 14/mai/2011 11:27
par DarkVader
Je parle zone mémoire
Dans ce contexte
Code : Tout sélectionner
proceduredll xxx()
protected *buffer=AllocateMemory(1000)
endprocedure
est-ce qu'un freememory est opéré automatiquement sur *buffer à la sortie de la procédure ?
Re: Libération de zone mémoire
Publié : sam. 14/mai/2011 11:36
par Fred
Non, pas a la fin d'une procedure, seulement quand le programme se termine ou que la DLL is dechargée.
Re: Libération de zone mémoire
Publié : sam. 14/mai/2011 13:46
par DarkVader
Merci,
c'est ce que je craignais.
En fait, dans une procédure j'ai écrit la gestion d'erreurs suivante:
Code : Tout sélectionner
ProcedureDll xxxx()
Protected *buffer
OnErrorGoto (?ProcErrHandler)
;.... traitement
Allocate
FreeMemory
; ... end traitement
ProcedureReturn yyyy
ProcErrHandler:
;traitement erreur
...
FreeMemory *Buffer
OnErrorDefault()
ProcedureReturn 0
EndProcedure
et j'ai du coup un nouvelle question :
Dans le cas où une erreur se produise avant que l'allocation de *buffer ait eu lieu
est-ce que FreeMemory (exécuté dans ProcErrHandler) lèvera une nouvelle exception ?
En bref, le traitement décrit est-il correct ?
Re: Libération de zone mémoire
Publié : sam. 14/mai/2011 16:37
par Chris
Fred a écrit :Non, pas a la fin d'une procedure, seulement quand le programme se termine ou que la DLL is dechargée.
Fred, il faudrait voir à venir un peu plus ici, et un peu moins chez les anglais, ça se ressent dans ton orthographe.
C'est le début du syndrome JCVD.
Dans pas longtemps, tu vas être "aware"

Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 9:54
par Fred
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 15:09
par DarkVader
Bravo, c'est bien de troller un thread mais ça ne répond pas à ma 2ème question

Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 15:17
par Chris
DarkVader a écrit :Bravo, c'est bien de troller un thread mais ça ne répond pas à ma 2ème question

Ooops!...Désolé!
Mais c'était difficile de résister.

Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 16:39
par case
DarkVader a écrit :Merci,
c'est ce que je craignais.
En fait, dans une procédure j'ai écrit la gestion d'erreurs suivante:
Code : Tout sélectionner
ProcedureDll xxxx()
Protected *buffer
OnErrorGoto (?ProcErrHandler)
;.... traitement
Allocate
FreeMemory
; ... end traitement
ProcedureReturn yyyy
ProcErrHandler:
;traitement erreur
...
FreeMemory *Buffer
OnErrorDefault()
ProcedureReturn 0
EndProcedure
et j'ai du coup un nouvelle question :
Dans le cas où une erreur se produise avant que l'allocation de *buffer ait eu lieu
est-ce que FreeMemory (exécuté dans ProcErrHandler) lèvera une nouvelle exception ?
En bref, le traitement décrit est-il correct ?
a mon avis cela créera une autre erreur vu que la mémoire n'est pas allouée et que tu veux libérer une mémoire non allouée
pour éviter cela tu peux faire un ReAllocateMemory(*buffer,1) avant de libérer la mémoire
car dans le cas ou la mémoire est bien allouée elle est ré-allouée donc ca n'est pas génant. et dans le cas ou elle n'est pas déja allouée elle l'est maintenant et peut être libérée sans erreur.
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 17:01
par DarkVader
n'est-il pas équivalent ?
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 17:34
par case
non car si par exemple tu alloue un buffer a un moment donné dans ta variable *buffer celle ci contiens toujours l'adresse memoire du buffer meme si tu l'a libéré
Code : Tout sélectionner
*buffer=AllocateMemory(2000)
Debug *buffer
FreeMemory(*buffer)
;
;
;
If *buffer
FreeMemory(*buffer)
EndIf
ou alors il faut effacer le contenu de *buffer en même temps que tu libère la mémoire
Code : Tout sélectionner
*buffer=AllocateMemory(2000)
Debug *buffer
FreeMemory(*buffer):*buffer=0
;
;
;
If *buffer
FreeMemory(*buffer)
EndIf
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 18:04
par DarkVader
OK
Je vais plutôt réinitialiser systématiquement *buffer à 0 après chaque FreeMemory
pour dans la gestion d'erreurs pouvoir effectuer le test.
Ça me semble plus propre.
Merci.
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 18:49
par case
tu peux passer par une macro
Code : Tout sélectionner
Macro FreeMem (var)
FreeMemory(var)
var=0
EndMacro
*buffer=AllocateMemory(500)
debug *buffer
FreeMem(*buffer)
debug *buffer
Re: Libération de zone mémoire
Publié : dim. 15/mai/2011 20:31
par G-Rom
Tu peut aussi utilisé un système de pointeur intelligent , le pointeur vérifie qu'aucune variable ne pointe sur lui.
Code : Tout sélectionner
; Pointeur intéligent
Structure smartPointer
mPointer.i
mNbLink.i
List mPtrList.i()
EndStructure
Procedure.i New(size.i)
*sp.smartPointer = AllocateMemory(SizeOf(smartPointer))
*sp\mPointer = AllocateMemory(size)
*sp\mNbLink = 0
InitializeStructure(*sp,SmartPointer)
ProcedureReturn *sp
EndProcedure
Procedure.b Delete(*smartPointer.smartPointer)
If *smartPointer
ForEach *smartPointer\mPtrList()
Pointer = *smartPointer\mPtrList()
Value = PeekI(Pointer)
If Value <> *smartPointer\mPointer
*smartPointer\mNbLink - 1
EndIf
Next
If *smartPointer\mNbLink < 0
*smartPointer\mNbLink = 0
EndIf
If *smartPointer\mNbLink = 0
FreeMemory(*smartPointer\mPointer)
FreeMemory(*smartPointer)
ProcedureReturn #True
EndIf
EndIf
Debug "Impossible de libérer le smartPointer , il est lié "+Str(*smartPointer\mNbLink)+ " fois."
ProcedureReturn #False
EndProcedure
Procedure Assign(*smartPointer.smartPointer, pointer.i)
If *smartPointer<>0
AddElement(*smartPointer\mPtrList())
*smartPointer\mPtrList() = pointer
PokeI(pointer,*smartPointer\mPointer)
*smartPointer\mNbLink + 1
EndIf
EndProcedure
Procedure GetNbLink(*smartPointer.smartPointer)
If *smartPointer<>0
ProcedureReturn *smartPointer\mNbLink
EndIf
EndProcedure
Procedure SmartPointer_PokeI(*smartPointer.SmartPointer, value.i)
If *smartPointer
If *smartPointer\mNbLink > 0
PokeI(*smartPointer\mPointer,value)
EndIf
EndIf
EndProcedure
Procedure.i SmartPointer_PeekI(*smartPointer.SmartPointer)
If *smartPointer
If *smartPointer\mNbLink > 0
ProcedureReturn PeekI(*smartPointer\mPointer)
EndIf
EndIf
EndProcedure
SmartPointer = New(1000) ; Allocation de 1000 bytes
*PointeurA = #Null
*PointeurB = #Null
Assign(SmartPointer, @*PointeurA)
Assign(SmartPointer, @*PointeurB)
; Ecriture dans la zone mémoire
PokeI(*PointeurA, 527)
;ou comme ca :
SmartPointer_PokeI(SmartPointer,527)
; Lecture dans la zone mémoire
Debug PeekI(*PointeurB)
; ou comme ca :
Debug SmartPointer_PeekI(SmartPointer)
Delete(SmartPointer) ; On ne peut pas l'effacer ! , il est lié 2 fois !
; Le smartPointer existe toujours.
*Hacking = *PointeurA ; Comportement dangereux , *Hacking n'est pas répertorié dans le smart pointer , a évité donc !
*PointeurA = #Null ; on coupe les liens avec le smartPointer
*PointeurB = #Null
Delete(SmartPointer) ; On libère la zone mémoire , il n'est plus lié, donc c'est bon.
Debug "Le smartPointer est bien effacé"