SysFreeMem, функция

Синтаксис


function SysFreeMem(P:  Pointer):  Integer;

Описание

Функция SysFreeMem использует встроенный менеджер памяти Delphi для освобождения памяти, на которую ссылается указатель Р. Возвращает ноль в случае успеха и ненулевой код ошибки, если Р - некорректный указатель или nil.
SysFreeMem - настоящая функция.

Ошибки

Советы и приемы

  • SysFreeMem применяется при разработке собственного менеджера памяти как фильтр для вызова из него подпрограмм встроенного менеджера памяти Delphi.
  • Если вы не создаете менеджер памяти, вызывайте для освобождения памяти процедуры Dispose или FreeMem, а не функцию SysFreeMem.
  • FreeMem и Dispose сами проверяют значение указателя на nil, вот почему SysFreeMem этого не делает.

Пример


// Пояснения по этому менеджеру памяти приведены в описании процедуры
// SetMemoryManager.

// Возвращает True, если память, на которую указывает PArray, является
// корректным блоком из кучи и защитные слова не были изменены.
// Возвращает False при любой ошибке.
function GuardsAreOkay(PArray: PIntegerArray; Fill: Boolean): Boolean;
const
  DelphiInUseFlag = 2;
  MemMgrFlags = 7;
var
  Size: LongWord;
begin
  // Сначала определяем размер блока, Размер представляет собой
  // длинное слово перед началом блока. Delphi устанавливает размер
  // и флаги в трех младших битах. Этот формат может измениться
  // в будущих версиях. Для выделенного блока средний бит равен 1.
  PArray := PIntegerArray(PChar(PArray) - SizeOf(Size));
  Size := PArray[0];
  PArray := PIntegerArray(PChar(PArray) + SizeOf(Size));

  if (Size and DelphiInUseFlag) <> DelphiInUseFlag then
  begin
    Result := False;
    Exit;
  end;

  // Удаляем флаг, выставлений в Delphi, и вычитаем размер
  // заголовка.
  Size := Size and not MemMgrFlags - SizeOf(Size);

  // Праверящем защитные слова.
  if PArray[0] <>AllocatedGuard then
    Result := False

  // Размер включает два защитных слова, поэтому конечное
  // защитное слово расположено по индексу size-1.
  else if PArray[Size div GuardSize - 1] <> AllocatedGuard then
    Result := False
  else
  begin
    // Если мы дошли до этого места, блок правильный.
    Result := True;

    // Если вызывающая сторона требует этого (как DebugFree), весь блок
    // заполняется специальным битовым шаблоном FreeFill, что
    // помогает обнаруживать проблемы, связанные со ссылками
    // на освобожденную память.
    if Fill then
      FillChar(PArray^, Size div 2, FreeFill);

    // Изменение значений защитных слов на FreeGuard, даже если
    // вызывающая сторона не хочет заполнять весь блок.
    PArray[0] := FreeGuard;
    PArray[Size div GuardSize - 1] := FreeGuard;
  end;
end;

// Возвращает ноль в случае успеха и ненулевое значание
//в случае неудачи.
function DebugFree(Mem: Pointer): Integer;
var
  PArray: PIntegerArray;
begin
  // Получение указателя на истинное начало блока памяти.
  PArray := PIntegerArray(PChar(Mem) - GuardSize);

  if not GuardsAreOkay(PArray, True) then
    Result  := 1
  else
    Result  := SysFreeMem(PArray);
end;

Смотрите также

Процедуры Dispose, FreeMem, GetMemoryManager, SetMemoryManager, функции FreeMemory, IsMemoryManagerSet, SysGetMem, SysReallocMem.
    Учебник по языку Pascal          Лабораторные работы по программированию          Справочник




Нет комментариев.



Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: