2009-06-09 4 views
1

Je veux obtenir la taille de tout type "record" dans la fonction suivante. Mais semble que cela ne fonctionne pas:Est-il possible d'obtenir la taille du type pointé par un pointeur dans Delphi 7?

function GetDataSize(P : Pointer) : Integer; 
begin 
    Result := SizeOf(P^); // **How to write the code?** 
end; 

Par exemple, la taille de l'enregistrement suivant est 8 octets

SampleRecord = record 
Age1 : Integer; 
Age2 : Integer; 
end; 

Mais GetDataSize(@a) retourne toujours 1 (a est une variable de type SampleRecord bien sûr). Que devrais-je faire?

J'ai remarqué que Delphi a une procédure procédure Nouveau (var P: pointeur) qui peut allouer le bloc de mémoire correspond à la taille du type que pointe P. Comment peut-il obtenir la taille?

Répondre

7

vraiment complexe. La raison pour laquelle New sait la quantité de mémoire à allouer est que New est compilateur . magie C'est un langage intégré, donc quand le compilateur voit que vous appelez, ce récrit à quelque chose comme ceci:.

// New(foo); 
foo := System._New(SizeOf(foo^), TypeInfo(TypeOf(foo^))); 

TypeOf est ici une confectionnée fonction Delphi à des fins expositoires le compilateur sait le type déclaré de foo car il sait où se trouvent toutes vos déclarations de variables sont. Vous pouvez regarder l'implémentation de _New dans System.pas. Une réécriture similaire se produit pour Dispose afin qu'il sache quel genre de finalisation à faire avant de libérer la mémoire.

Les idées de variables et déclarations sont des concepts de compilation. Au moment de l'exécution, ils cessent d'exister. Au moment de l'exécution, un pointeur est juste une adresse. Le type de ce qu'il pointe a été déterminé au moment de la compilation. Les types sont ce qui détermine la taille de quelque chose.

Si vous avez besoin d'écrire une fonction qui accepte des pointeurs vers plusieurs choses de tailles différentes, alors vous devrez juste fournir un second paramètre qui décrit ce à quoi pointe le premier.

Découvrez une autre question ici, "How to know what type is a var." Le demandeur se demandait comment déterminer plus d'informations sur une variable donnée seulement son adresse.

+0

@Rob, merci pour les informations détaillées, je crois que c'est complier la magie. Je pense que cela explique aussi pourquoi il n'y a pas de "nouvelle" procédure. – trudger

0

Delphi dispose d'un gestionnaire de mémoire intégré. Je crois nouveau a accès à l'objet tas et utilise HeapSize() (ou des routines similaires) pour obtenir la taille d'un bloc, pour certains pointeur.

+0

Le gestionnaire de mémoire est remplaçable, mais cette capacité fait partie de la définition. Les fonctionnalités clés comme les tableaux d'affichage et les tableaux dynamiques ne fonctionneront pas sans cela. –

3

Vous ne pouvez pas trouver la taille de la structure de données en utilisant une variable de type Pointer, car le compilateur ne peut pas faire une supposition et la vérifier car le pointeur peut pointer sur n'importe quel type de données. Vous pouvez lire quelques informations here.

2

Il n'existe aucun moyen sûr de déterminer la taille d'un enregistrement pointant vers un pointeur. Cependant, si vous avez alloué la mémoire vers laquelle pointe le pointeur, vous pouvez demander la taille de ce bloc de mémoire. Mais là encore, puisque vous avez alloué ce bloc, vous devriez déjà connaître la taille de ce bloc! Le gestionnaire de mémoire Delphi conserve la trace de chaque bloc de mémoire alloué. Avec les informations du gestionnaire de mémoire, il est possible de trouver cette information, si votre pointeur pointe vers le début d'un bloc de mémoire. Cependant, si vous avez alloué un gros bloc de mémoire, chargé des données dans celui-ci et que votre pointeur pointe vers des données à l'intérieur de ce bloc, cette méthode serait assez peu fiable. En outre, si vous utilisez des types référencés (tableaux dynamiques, chaînes, classes, etc.) dans votre enregistrement, la taille qu'il renvoie sera toujours inutilisable puisque vous obtenez la taille de la référence (4 octets) au lieu de la taille des données auxquelles il est fait référence.

La commande NEW() utilise simplement les informations de type du type de données que vous lui passez pour obtenir sa taille. Pour savoir comment cela fonctionne exactement, vous pouvez simplement vérifier le code source Delphi. Ouvrez \ source \ Win32 \ rtl \ sys \ System.pas et recherchez "_New". (Avec le trait de soulignement devant lui. L'utilisation de ce code source peut vous aider à comprendre comment gère Delphi les allocations de mémoire, bien que le code source peut être

Questions connexes