Wie finde ich die Größe des Speichers, auf den ein Zeiger verweist?

8
Mit

GetMem können Sie einen Puffer beliebiger Größe zuweisen. Irgendwo wird die Größeninformation vom Speichermanager beibehalten, weil Sie nicht wissen müssen, wie groß der Puffer ist, wenn Sie den Zeiger auf FreeMem übergeben.

Ist diese Information nur für den internen Gebrauch oder gibt es eine Möglichkeit, die Größe des Puffers abzurufen, auf den ein Zeiger zeigt?

    
Mason Wheeler 23.08.2009, 18:55
quelle

5 Antworten

8

Es scheint, dass die Größe eines Blocks, auf den ein Zeiger verweist, der von GetMem () zurückgegeben wird, irgendwo verfügbar sein muss, vorausgesetzt, FreeMem () erfordert dies nicht Sie identifizieren die Größe des Speichers, der freigegeben werden soll - das -System muss das ermitteln können, also warum nicht der Anwendungsentwickler?

Aber wie andere gesagt haben, sind die genauen Einzelheiten der Speicherverwaltung NICHT vom System selbst definiert ... Delphi hatte immer eine austauschbare Speichermanagerarchitektur und die "Schnittstelle" für kompatible Speicherverwalter erfordert nicht, dass sie diese Informationen für einen beliebigen Zeiger bereitstellen.

Der Standard-Speicher-Manager wird die notwendigen Informationen in der ihm angemessenen Weise speichern, aber ein anderer Speicher-Manager wird mit Sicherheit einen völlig anderen, wenn auch oberflächlich ähnlichen Mechanismus verwenden, also selbst wenn Sie eine Lösung auf der Basis eines intimen Wissens hacken Speichermanager, wenn Sie den Speichermanager ändern (oder wenn er für Sie geändert wird, zB durch eine Änderung im System definiert, Speichermanager, den Sie vielleicht standardmäßig verwenden, wie er zB zwischen Delphi 2005 und 2006 vorkam) dann Ihre Lösung wird fast sicher brechen.

Im Allgemeinen ist es keine unzumutbare Annahme seitens des RTL / Speicher-Managers, dass die Anwendung bereits wissen sollte, wie groß ein Stück Speicher ist, auf den sich ein GetMem () zugewiesener Zeiger bezieht die Anwendung hat es in erster Linie verlangt! :)

Und wenn Ihre Anwendung den Zeiger NICHT zugewiesen hat, dann hat der Speichermanager Ihrer Anwendung absolut keine Möglichkeit zu wissen, wie groß der Block sein könnte, auf den er verweist. Es kann beispielsweise ein Zeiger in die Mitte eines größeren Blocks sein - nur die Quelle des Zeigers kann möglicherweise wissen, wie sie sich auf den Speicher bezieht, auf den sie verweist!

Aber, wenn Ihre Anwendung wirklich solche Informationen über ihre eigenen Zeiger verwalten muss, könnte sie natürlich leicht ein Mittel finden, um dies mit einer einfachen Singleton-Klasse oder -Funktionsbibliothek zu erreichen, durch die < strong> GetMem () / FreeMem () Anforderungen werden weitergeleitet, um eine Aufzeichnung der zugeordneten angeforderten Größe für jeden aktuell zugewiesenen Zeiger zu führen. Solch ein Mechanismus könnte dann natürlich diese Information bei Bedarf vollständig zuverlässig und unabhängig von dem Speichermanager, der gerade verwendet wird, verfügbar machen.

Dies kann die einzige Option sein, wenn ein " genauer " Datensatz erforderlich ist, da eine bestimmte Speichermanagerimplementierung für eine gegebene Datenmenge einen größeren Speicherblock zuweisen kann, als tatsächlich angefordert wird . Ich weiß nicht, ob ein Speichermanager das tatsächlich tut, aber theoretisch könnte es das aus Effizienzgründen tun.

    
Deltics 23.08.2009, 21:23
quelle
5

Es ist für den internen Gebrauch gedacht, da es vom verwendeten MemoryManager abhängt. BTW, deshalb müssen Sie das Paar GetMem / FreeMem vom selben MemoryManager verwenden; es gibt keine kanonische Art zu wissen, wie der Speicher reserviert wurde.
Wenn Sie sich in Delphi FastMM4 ansehen, können Sie sehen, dass der Speicher in kleinen, mittleren oder großen Blöcken zugewiesen wird:
 Die kleinen Blöcke werden in Pools mit Blöcken fester Größe zugewiesen (Blockgröße wird auf Poolebene im Blocktyp definiert)

%Vor%

Die mittleren Blöcke werden ebenfalls in Pools zugewiesen, haben aber eine variable Größe

%Vor%

Die großen Blöcke werden einzeln mit der erforderlichen Größe zugewiesen

%Vor%     
François 23.08.2009 20:01
quelle
0
  

Ist diese Information nur für den internen Gebrauch oder gibt es eine Möglichkeit, die Größe des Puffers abzurufen, auf den ein Zeiger zeigt?

Widersprechen sich diese beiden "Alternativen"?

Es ist nur für den internen Gebrauch.

    
Pavel Shved 23.08.2009 19:07
quelle
0

Vor dem zugewiesenen Bereich befinden sich einige Informationen zum Speichern von Metainformationen. Das bedeutet, dass jedes Mal, wenn Sie ein Stück Speicher reservieren, ein größeres Stück zugewiesen wird und die ersten Bytes für Metainformationen verwendet werden. Der zurückgegebene Zeiger folgt dem Block, der auf diese Metainformationen folgt.

Ich kann mir vorstellen, dass das Format mit einer anderen Version des Speichermanagers geändert wird, also zähle nicht darauf.

    
Toon Krijthe 23.08.2009 19:20
quelle
0

Diese Informationen sind nur für den internen Gebrauch bestimmt.

Beachten Sie, dass Speichermanager die Größe nicht als Teil des zurückgegebenen Speichers speichern müssen. Viele Speichermanager speichern sie in einer internen Tabelle und verwenden die Speicheradresse des Anfangs des Chunks, der als Suchschlüssel ausgegeben wird diese Tabelle.

    
nos 23.08.2009 19:32
quelle