Diese Frage betrifft die Funktionen und malloc
von Foreign.Marshal.Alloc
und newForeignPtr
und mallocForeignPtr
von Foreign.ForeignPtr
. Wo lebt die zugeteilte Erinnerung und wie behandelt der Müllsammler sie?Woher bezieht GHC fremdes Gedächtnis und wie behandelt der Müllsammler es?
Antwort
malloc
ruft die C malloc()
, so dass es Speicher auf dem C-Heap reserviert, die Sie manuell freigeben müssen. (Sie können auch, dass aus C mit free()
wenn Sie möchten.)
alloca
und mallocForeignPtr
zurechnen Bytefeldgruppen gepinnt, die auf der Haskell gepinnt Haufen leben. Der GC wird diese automatisch freigeben, wenn sie nicht mehr benötigt werden, aber sie werden sie niemals verschieben (da sie angeheftet sind), sodass Sie ihre Adressen an eine C-Funktion übergeben können.
newForeignPtr
scheint nicht relevant für Ihre Frage.
Der Speicher von Ptr a
zugewiesen von malloc
lebt auf dem Heap, wie in der Programmiersprache C. Es wird vom Garbage Collector ignoriert - Sie müssen es manuell mit free
manuell freigeben, und seien Sie vorsichtig, es danach nie wieder zu verwenden.
alloca f
macht eine ähnliche Zuordnung, rufen Sie f
mit dem Zeiger, und geben Sie den Speicher danach frei. Der Zeiger darf nicht verwendet werden, nachdem f
zurückgegeben wurde.
Diese Routinen sind nicht dazu gedacht, im alltäglichen Code verwendet zu werden, sondern nur zur Verbindung mit anderen Sprachen, unter Verwendung einer C-ähnlichen Schnittstelle (FFI). Sie erhalten genau die gleichen Speichersicherheitsgarantien, die C bietet - also praktisch keine. Als solches ist es ziemlich gefährlich und sollte mit großer Vorsicht verwendet werden.
Zum Vergleich, die ForeignPtr
-pointed Speicher noch auf dem Heap, aber wird Müll gesammelt werden, nachdem keine Zeiger mehr (d. H. Haskell ForeignPtr a
) beziehen sich auf den Speicher. Beachten Sie, dass selbst wenn Garbage Collection hier verwendet wird, diese Art von Zeigern nicht risikofrei ist. In der Tat, wenn Haskell keine Live-Zeiger mehr auf den Speicher hat, wird die Laufzeit ihn freigeben, selbst wenn dieser Zeiger noch in der Fremdsprache aktiv ist. Der Programmierer muss sicherstellen, dass dies nie passieren wird.
Alle zuweisen dynamischen Speicher und es ist auf dem Haufen.
Die ungerade ist malloc
; Der von malloc zugewiesene Speicher muss explizit freigegeben werden.
alloca
reserviert temporären dynamischen Speicher und übergibt ihn an eine Berechnung. Der Speicher wird automatisch freigegeben, wenn die Berechnung beendet ist.
mallocForeignPtr
reserviert Speicher und gibt einen fremden Zeiger zurück. Der Speicher wird automatisch freigegeben, wenn der Zeiger verworfen wird.
newForeignPtr
fügt einen neuen Verweis auf einen vorhandenen dynamisch zugewiesenen Speicher hinzu. Der Speicher wird NUR freigegeben, wenn der letzte Verweis auf das Objekt gelöscht wird.
Wenn Sie wissen, C++: malloc
ist die nackte new
, malloca
ist die unique_ptr/auto_ptr
, mallocForeignPtr
und newForeignPtr
shared_ptr
sind.
Das 'ForeignPtr'-Zeug sieht wesentlich schöner aus (es befreit den Speicher automatisch). – dfeuer
Ich habe die Frage vergessen erwähnt, dass ... guter Punkt. – chi
Obwohl ich mir vorstellen, dass Sie es wahrscheinlich nicht für ausländische Zeiger zu fremden Zeigern verwenden können .... – dfeuer