Libération de zone mémoire

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
DarkVader
Messages : 95
Inscription : mer. 11/juil./2007 10:56

Re: Libération de zone mémoire

Message par DarkVader »

L'idée est intéressante : à l'image de AddRef/Realease utilisé par COM
mais inutile dans mon cas.

Merci tout de même - je garde sous le coude pour une autre utilisation.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Re: Libération de zone mémoire

Message par Anonyme2 »

J'utilise ce code dans PureIconManager pour la gestion de la mémoire (pas depuis une dll)

Je tiens une liste chainée en global créée au début du programme qui stocke les adresses des mémoires allouées.

Dans la procédure de libération de mémoire, si l'adresse correspond à une entrée de la liste chainée alors je libère la mémoire et je supprime l'élément correspondant de la liste.
il fut un temps ou IsMemory existait et c'était très pratique, mais on l'a perdu depuis et je ne sais pas pourquoi. J'ai donc recréé un truc similaire.

En plus, sur de longs codes (ou petits), ça permet d'afficher avant l'appel d'une procédure, le nombre d'éléments de la liste et à la sortie de comparer pour voir si on en a oublié.

J'ai laissé l'appel à PIM_SetError_Code() qui écrit le code d'erreur correspondante dans une variable que je teste si le retour vaut 0.

Code : Tout sélectionner

;// liste chainée de la gestion mémoire
Global NewList Memory_pointer() 


Procedure.i PIM_AllocateMemory(Taille.l)
     ;///////////////////////////////////////////////////////////////////////////////////////////////////
     ;//
     ;// FONCTION: PIM_AllocateMemory()
     ;//
     ;// BUT: allouer de la mémoire et ajouter l'adresse mémoire à une liste chainée
     ;//      utilisée lors de la désallocation pour éviter les plantage mémoire
     ;//
     ;// PARAMS: Taille - La taille des données à allouer
     ;//
     ;// RETOURNE: L'adresse mémoire allouée
     ;//           #Return_Error (=#False) si la mémoire n'est pas allouée
     ;//
     ;///////////////////////////////////////////////////////////////////////////////////////////////////
     
     ;// teste si la taille est différente de 0, 0 interdit
     If Taille = #Null
          PIM_SetError_Code(#Error_Code_Unable_To_Allocate_Memory)
          ProcedureReturn #Return_Error
     EndIf
     
     ;// ajoute un élément à la liste
     If AddElement(Memory_pointer()) = #Null
          PIM_SetError_Code(#Error_Code_Unable_To_Allocate_Memory)
          ProcedureReturn #Return_Error
     EndIf
     
     ;// alloue la mémoire demandée
     Memory_pointer() = AllocateMemory(Taille)
     If Memory_pointer() = 0
          DeleteElement(Memory_pointer())
          PIM_SetError_Code(#Error_Code_Unable_To_Allocate_Memory)
          ProcedureReturn #Return_Error
     EndIf
     
     ;// retourne l'adresse de la mémoire allouée
     ProcedureReturn Memory_pointer()
EndProcedure

Procedure PIM_FreeMemory(*Memory)
     ;///////////////////////////////////////////////////////////////////////////////////////////////////
     ;//
     ;// FONCTION: PIM_FreeMemory()
     ;//
     ;// BUT: Libérer la mémoire
     ;//      un test est réalisé sur la valeur (dans la liste chainée) pour éviter les plantages
     ;//
     ;// PARAMS: *Memory - l'adresse mémoire à libérer
     ;//
     ;// RETOURNE: Rien
     ;//
     ;///////////////////////////////////////////////////////////////////////////////////////////////////
     
     ForEach Memory_pointer()
          If *Memory
               If *Memory = Memory_pointer()
                    FreeMemory(*Memory)
                    DeleteElement(Memory_pointer())
                    Break
               EndIf
          EndIf
     Next
EndProcedure
et pour créer une mémoire

Code : Tout sélectionner

*Memory = PIM_AllocateMemory(3000)
et la libérer

Code : Tout sélectionner

PIM_FreeMemory(*Memory)
Répondre