Есть какая-нибудь разница между Маллоком и Маршалом. - PullRequest
10 голосов
/ 27 января 2012

Я пишу модуль в C #, который экспортирует некоторые функции для использования в C. Мне нужно выделить немного памяти для некоторых структур, которые будут передаваться между C <-> C #.

Что я выделяю в CIс malloc, а в C # я делаю с Marshal.AllocHGlobal () (чтобы выделить неуправляемую память для передачи в C).

Есть ли проблема, если я освобождаю () память, выделенную с Marshal.AllocHGlobal, иесли я освобожу память с Marshal.FreeHGlobal (), который был выделен с помощью malloc?

Спасибо

Ответы [ 2 ]

18 голосов
/ 27 января 2012

Золотое правило заключается в том, что вы должны освободить из той же кучи, которая использовалась для выделения памяти.

Если вы выделите ее с помощью malloc(), вы должны освободить ее с free() из той жеC RTL.Аналогичным образом, на управляемой стороне AllocHGlobal() должно быть сбалансировано на FreeHGlobal().

Теперь AllocHGlobal() реализуется путем вызова функции Win32 LocalAlloc.Таким образом, вы можете освободить такую ​​память с помощью вызова LocalFree на родной стороне.И наоборот.

Если вы хотите использовать кучу, которая является общей для собственной и управляемой, более распространенным является использование кучи COM.На родной стороне используйте CoTaskMemAlloc() и CoTaskMemFree().На управляемой стороне используйте Marshal.AllocCoTaskMem() и Marshal.FreeCoTaskMem().

Однако вам следует избегать проектирования системы подобным образом.Гораздо проще придерживаться правила, согласно которому вся память, выделенная на управляемой стороне, освобождается там, а также для собственной стороны.Если вы не будете следовать этому правилу, скорее всего, вы скоро потеряете информацию о том, кто за что отвечает.

3 голосов
/ 27 января 2012

Может возникнуть или не возникнуть проблема - это полностью зависит от реализации. Никогда не полагайтесь на детали реализации функциональности вашего приложения!

Поэтому я рекомендую не использовать Marshal.AllocHGlobal(), malloc(), Marshal.FreeHGlobal() и free() крест-накрест.

Один пример, где вы столкнетесь с ужасными проблемами, - это если вы используете библиотеку, которая совершает какую-то причудливую malloc()/free() магию - вы можете даже не знать об этом.

...