2010-07-12 2 views
1

J'ai rencontré des erreurs où les objets sont en quelque sorte libérés mais nous finissons par appeler FreeMem. Bien sûr cela provoque une erreur puisque la mémoire a déjà été libérée et renvoie une erreur.Vérifier si la mémoire est allouée avant d'appeler FreeMem (Delphi 32)

Je sais qu'un bloc try-catch le corrigera probablement mais c'est beaucoup de blocs try-catch. Avec l'objet regular.free, le moyen d'éviter cela est FreeAndNil (objet) mais je ne trouve pas l'équivalent pour FreeMem. Quelque chose qui teste si elle est allouée ou non avant de la libérer.

Quelle est la meilleure solution ici en matière de facilité de lecture, de maintenabilité et de stabilité.

Répondre

7

L'équivalent à FreeAndNil serait juste

FreeMem(p); 
p := nil; 

Mais vous allez mieux résoudre le problème réel en conclusion qui vous utiliser l'objet après sa libération. Essayez FastMM - cela vous aidera dans cette tâche.

+1

Merci pour le conseil. J'ai repéré le problème et c'est en train de créer un objet que j'ai perdu la mémoire. Ceci lance une erreur et le contrôle retourne au bloc qui a appelé le create sur l'objet. Le problème est que le create est dans un bloc try-catch avec une section finally qui libère l'objet. Dans le détruire pour cet objet il appelle FreeMem (p) ainsi il s'avère que la mémoire n'a jamais été allouée en premier lieu. Je peux probablement résoudre ce problème en initiant tout p à zéro. – Daisetsu

+2

La partie du code qui alloue la ressource ne devrait jamais être dans le bloc 'try-finally ', elle devrait être immédiatement avant le' try'. S'il y a des raisons valables d'avoir AllocMem dans le bloc 'try-finally 'qui finit par appeler FreeMem dans' finally', alors affectez le pointeur 'nil' avant d'entrer dans' try' pour rendre le 'finally' sûr. –

+0

freemem est déjà VAR, vous pouvez donc simplement l'implémenter dans le gestionnaire de mémoire. La raison pour laquelle freeandnil existe est que vous n'avez pas de référence à l'endroit où la référence d'objet est stockée quand vous faites .Free; Vous avez seulement la valeur (l'objet) –

0

De toute façon, vous ne devriez pas appeler FreeMem sur un objet. Il doit être détruit avec son destructeur, en appelant Free sur celui-ci. Mais si vous travaillez avec des pointeurs vers d'autres choses (des enregistrements, par exemple), alors allez avec ce que dit Ulrich. (Les deux parties de celui-ci.)

+0

En fait, Daisetsu doit cesser d'appeler la mémoire obtenue à partir d'AllocMem un objet. –

+0

@Cosmin: Le mot "objet" n'est pas nécessairement défini de façon étroite. –

+0

A titre d'exemple d'Ulrich: les objets TP (que Delphi supporte toujours) peuvent être parfaitement alloués avec allocmem. Et les classes ont une instance pour une raison. –

Questions connexes