Gibt es einen Unterschied zwischen malloc und Marshal.AllocHGlobal?

7

Ich schreibe ein Modul in C #, das einige Funktionen exportiert, die in C verwendet werden sollen. Ich muss etwas Speicher für einige Strukturen zuweisen, die zwischen C & lt; - & gt; C #.

Was ich in C zuteile, mache ich mit malloc, und in C # mache ich mit Marshal.AllocHGlobal () (um nicht verwalteten Speicher zuzuordnen, der an C übergeben wird).

Gibt es irgendein Problem, wenn ich den Speicher freigebe, der mit Marshal.AllocHGlobal zugeteilt wird, und wenn ich Speicher mit Marshal.FreeHGlobal () freigebe, das mit malloc zugeteilt wurde?

Danke

    
bzamfir 26.01.2012, 22:34
quelle

2 Antworten

15

Die goldene Regel ist, dass Sie die Zuweisung von demselben Heap, der zur Zuweisung des Speichers verwendet wurde, aufheben müssen.

Wenn Sie es mit malloc() zuweisen, müssen Sie es mit der free() aus derselben C RTL freigeben. Und ebenso auf der verwalteten Seite sollte AllocHGlobal() sein ausgeglichen durch FreeHGlobal() .

Nun wird AllocHGlobal() durch Aufruf der Win32-Funktion LocalAlloc implementiert. Sie könnten also einen solchen Speicher mit einem Aufruf von LocalFree auf der nativen Seite freigeben. Und umgekehrt.

Wenn Sie einen Heap verwenden möchten, der zwischen nativ und verwaltet geteilt wird, ist es üblich, den COM-Heap zu verwenden. Auf der nativen Seite verwenden Sie CoTaskMemAlloc() und CoTaskMemFree() . Auf der verwalteten Seite verwenden Sie Marshal.AllocCoTaskMem() und Marshal.FreeCoTaskMem() .

Sie sollten jedoch vermeiden, das System so zu gestalten. Es ist viel einfacher, an einer Regel festzuhalten, dass der gesamte auf der verwalteten Seite zugewiesene Speicher dort freigegeben wird, und ebenso für die native Seite. Wenn Sie dieser Regel nicht folgen, verlieren Sie wahrscheinlich bald den Überblick darüber, wer für was verantwortlich ist.

    
David Heffernan 26.01.2012, 22:40
quelle
4

Es kann sein, dass es ein Problem gibt oder nicht - das hängt vollständig von der Implementierung ab. Verlassen Sie sich nie auf ein Implementierungsdetail für Ihre App-Funktionalität!

Ich empfehle daher nicht , Marshal.AllocHGlobal() , malloc() , Marshal.FreeHGlobal() und free() kreuzweise zu verwenden.

Ein Beispiel, wo du in ernsthafte Schwierigkeiten geraten wirst, ist, wenn du eine Bibliothek benutzt, die irgendeine Art von Fantasie macht - vielleicht weißt du das gar nicht.

    
Eugen Rieck 26.01.2012 22:41
quelle

Tags und Links