Чтобы иметь возможность передавать произвольные значения указателя в эту функцию, вам нужно следовать той же модели, что и FreeAndNil, и передавать нетипизированный параметр .В противном случае компилятор правильно жалуется на то, что фактические и формальные типы параметров не идентичны.Приведите тип нетипизированного параметра к Pointer, когда вы вызываете FreeMem для него.
Вы делаете пару бессмысленных действий в этой функции.
Прежде всего, это освобождение нулевого указателя.всегда безопасно, поэтому нет причин проверять это перед вызовом FreeMem.Это освобождение не-нулевого указателя, о котором вам нужно беспокоиться, но никакая функция не может защитить вас от этого.
Далее, параметр размера для FreeMem игнорировался в течение многих лет.Раньше считалось, что если вы предоставили этот параметр, он должен был соответствовать размеру, переданному в GetMem, но в настоящее время FreeMem полностью игнорирует этот параметр - компилятор даже не передает этот параметр в функцию.
СИмея в виду все вышесказанное, ваша функция сводится к следующему:
procedure FreeMemAndNil(var P);
var
Tmp: Pointer;
begin
Tmp := Pointer(P);
Pointer(P) := nil;
FreeMem(Tmp);
end;
Будьте осторожны, чтобы случайно не вызвать эту функцию для всего, что не является указателем, выделенным с помощью GetMem.Компилятор не поймает его за вас, как если бы вы использовали типизированные параметры.Если вы попытаетесь освободить то, что не было выделено с помощью GetMem, вы, вероятно, получите исключение EInvalidPointer, но переданная вами переменная все равно будет равна нулю.То же самое работает FreeAndNil.