Нет, вы не можете просто использовать любой метод, который хотите освободить память. Вы ДОЛЖНЫ использовать все, что требует от вас распределитель . Только диспетчер памяти, который выделяет данный блок памяти, знает, как правильно освободить этот блок памяти.
Например, документация для Marshal.AllocHGlobal()
гласит:
Этот метод предоставляет функцию Win32 LocalAllo c из Kernel32.dll .
Когда AllocHGlobal вызывает LocalAllo c, он передает флаг LMEM_FIXED , что приводит к блокировке выделенной памяти на месте. Кроме того, выделенная память не заполнена нулями.
И документация для LocalAlloc()
гласит:
Чтобы освободить памяти, используйте функцию LocalFree . Не безопасно освобождать память, выделенную с помощью LocalAllo c с использованием GlobalFree.
Вот что Marshal.FreeHGlobal()
использует:
FreeHGlobal предоставляет функцию LocalFree из Kernel32.DLL , которая освобождает все байты, так что вы больше не можете использовать память, на которую указывает hglobal.
Итак, это разрешено для C# код для выделения памяти, используя Marshal.AllocHGlobal()
, а затем код C ++ для освобождения этой памяти, используя LocalFree()
. И наоборот, для кода C ++ для выделения памяти с использованием LocalAlloc(LMEM_FIXED)
, а затем для C# кода для освобождения этой памяти с использованием Marshal.FreeHGlobal()
.
Аналогично, класс Marshal
также имеет Marshal.AllocCoTaskMem()
метод:
Этот метод предоставляет функцию COM CoTaskMemAllo c , которая называется распределителем памяти задач COM.
Память, выделенная с помощью CoTaskMemAlloc()
, освобождается с помощью CoTaskMemFree()
:
Освобождает блок памяти задач, ранее выделенный посредством вызова CoTaskMemAllo c или CoTaskMemReallo c функция.
Что и используется Marshal.FreeCoTaskMem()
:
FreeCoTaskMem предоставляет COM CoTaskMemFree функция , которая освобождает все байты, так что вы больше не можете использовать память, на которую указывает параметр ptr.
Итак, для кода C# разрешено выделять память с использованием Marshal.AllocCoTaskMem()
а затем для кода C ++ освободить эту память, используя CoTaskMemFree()
. И наоборот, для кода C ++ для выделения памяти с использованием CoTaskMemAlloc()
, а затем для кода C# для освобождения этой памяти с использованием Marshal.FreeCoTaskMem()
.
Теперь, как говорится, менеджер памяти, который C ++ использует для своих new
и delete
операторов определяются реализацией . Нет никакой гарантии (или вероятности), что new
использует LocalAlloc()
или CoTaskMemAlloc()
, или что delete
использует LocalFree()
или CoTaskMemFree()
.
Таким образом, это недопустимо для C# для освобождения любой памяти, выделенной с помощью new
, или для C ++ до delete
любой памяти, выделенной с помощью C#.