0
votes

Quelle est la différence entre GetMem et AllocMem?

Dans Delphi, je vois plusieurs fonctions similaires pouvant être utilisées pour allouer de la mémoire, telles que GetMem et AllocMem. Quelles sont les différences entre eux?

J'ai lu le document et ne trouvez que GetMem n'initialisera pas la mémoire après une allocation, tandis qu'AllocMem.

Alors que je dois initialiser la mémoire après avoir appelé getMem? Le doc dit oui. Mais je vois dans un code source Delphi, ils n'appellent pas initialiser.

et si j'ai besoin de finaliser la mémoire après la finition? Je vois dans certains codes source Delphi, ils font, mais quelque chose qu'ils ne font pas.

merci


1 commentaires

Sorte de question étrange que vous fournissez la réponse dans le texte de votre question.


3 Réponses :


6
votes

logique semble simple - si vous avez besoin d'un tampon initialisé zéro, vous pouvez utiliser allocmem .

Si vous remplissez la mémoire tampon avec des données propres dans tout cas et n'utilisez jamais de contenu par défaut - vous pouvez utiliser getMem . .


0 commentaires

5
votes

La différence est que allocmem code> remplit le tampon nouvellement attribué avec des zéros, tandis que getMem code> n'est pas. Si votre code nécessite le tampon nouvellement attribué pour être tout-zeros initialement, vous pouvez utiliser allocmem code> au lieu d'écrire manuellement des zéros dans le tampon; Si vous ne vous souciez pas des octets initiaux dans le tampon, vous pouvez faire un (probablement) moins cher getMem code>.

Par exemple, P>

p := AllocMem(1024);
try
  p^ := 20;
  (p + 2)^ := p^ + (p + 1)^;
  ShowMessage((p + 2)^.ToString);
finally
  FreeMem(p);
end;


0 commentaires

1
votes

dépend de votre besoin. Avez-vous besoin d'un tampon et ne vous souciez pas de ce qu'il a initialement? Utiliser getMem.

getMem attribue un bloc de la taille donnée sur le tas et retourne L'adresse de cette mémoire dans le paramètre P. Les octets de la liste allouée Le tampon n'est pas réglé sur zéro. Pour éliminer le tampon, utilisez Freemem. Si il n'y a pas assez de mémoire disponible pour allouer le bloc, un L'exception EOUTOFMEMORY est soulevée.

REMARQUE: Si la mémoire doit être initialisée zéro, utilisez AllocMem à la place.

Si votre logique s'attend à ce que tous les octets de ce tampon soient zéro, utilisez AllocMem.

AllocMem attribue un bloc de la taille donnée sur le tas et renvoie l'adresse de cette mémoire. Chaque octet dans le tampon alloué est défini à zéro. Pour éliminer le tampon, utilisez Freemem. S'il n'y en a pas assez mémoire disponible pour allouer le bloc, une exception EOUTOFMEMORY est élevé.

Remarque: Si la mémoire n'a pas besoin d'être initialisée zéro, c'est plus efficace d'utiliser getMem à la place.

// et si j'ai besoin de finaliser la mémoire après la fin de la finition? Lorsque vous parlez d'une allocation de mémoire en général, la mémoire que vous allouez doit toujours être libérée.

Il y a peu d'exceptions à cela -

  • Lorsque vos objets sont comptés
  • Quand un autre objet prend soin d'un objet et libérant-le

5 commentaires

Merci. Je remarquerai simplement qu'il existe des procédures d'initialisation et de finalisation d'initialisation et de finalisez le tampon. Quand devrais-je invoquer la procédure finale?


Pourquoi vous sentez-vous la nécessité d'appeler finaliser ? Qu'est-ce qui doit exactement être finalisé? Pour les tableaux, vous utilisez des tableaux dynamiques et ils sont finalisés automatiquement. Si vous devez utiliser une allocation dynamique pour les enregistrements, vous utilisez nouveau et jetter et les avez donc finalisées. Pourquoi appelez-vous même getMem ou allocmem ? Personne ne peut offrir des conseils sans une compréhension claire du contexte?


Je ne m'occupe pas beaucoup de cette réponse, à cause de la dernière partie. Toute mémoire attribuée manuellement doit être traitée manuellement. Vous dites: "Il y a peu d'exceptions près", mais ce n'est pas vrai. Il n'y a pas d'exception. Si vous allouez avec getMem ou allocmem , vous devez appeler freemem . Si vous allouez avec Nouveau , vous devez appeler Disposer . Référence Des choses comptées telles que les chaînes, les matrices dynamiques, les interfaces, les méthodes anon, etc. ne sont pas attribuées à l'aide de getMem ou allocmem ou neuf . En ce qui concerne le transfert de propriété, c'est un peu orthogonal. Qui déléguette simplement la responsabilité.


@DavidHeffernan je parlais dans la dernière partie de sens plus général que l'allocmem ou GetMem


Ce n'est pas vraiment terriblement clair cependant, et la question est explicite dans la répartition de la mémoire manuelle. Peut-être qu'une partie du manque de clarté est en réalité un résultat de la question qui parle de finalisation. Je ne pense pas que l'astucieux signifie la répartition lorsqu'il dit la finalisation. Je pense qu'il désigne la finalisation en termes de types gérés. Mais si nous allons parler de types gérés, cela devrait être explicitement explicite dans la question, et plus loin, les types gérés ne doivent pas être attribués avec getMem ou allocmem .