Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Управление памятью в Delphi: хранение объектов в словарях и избежание утечек

Delphi , Синтаксис , Память и Указатели

В статье рассматривается важный аспект программирования на Delphi, связанный с управлением памятью при работе со словарями объектов. Особое внимание уделяется проблеме утечек памяти, которые могут возникать при неправильном освобождении объектов, добавленных в коллекции.

Проблема утечек памяти

При работе с коллекциями объектов в Delphi важно понимать, что объекты хранятся не по значению, а по ссылке (указателю или ссылке). Это означает, что при добавлении объекта в коллекцию, например, в TObjectDictionary, происходит не копирование объекта, а установка ссылки на него. Следовательно, если вы попытаетесь освободить объект после его добавления в коллекцию, вы убьете ссылку и коллекция будет содержать "висячую" ссылку, что приведет к утечке памяти.

Пример неправильной работы с объектами

myPOI := TMyPOI.Create;
{$ifdef FREE_MYPOI}
try
  myPOI.Value := Index;
  myPOI.Timestamp := NewTimeStamp;
  PoiDict.Add(username, myPOI);
{$ifdef FREE_MYPOI}
finally
  myPOI.Free;
end;

В приведенном выше коде создается объект myPOI, который затем добавляется в словарь PoiDict. После добавления в коллекцию происходит вызов myPOI.Free, который освобождает память, выделенную под объект, и коллекция начинает хранить уже несуществующий объект, что ведет к утечке.

Использование TObjectDictionary с передачей владения

Чтобы избежать подобных проблем, следует использовать TObjectDictionary, который позволяет передать владение над объектом коллекции, что позволяет ей самостоятельно управлять жизненным циклом объекта.

PoiDict := TObjectDictionary<string, TMyPOI>.Create([doOwnsValues]);

Исправление кода

function TForm2.CreateOrUpdate(username: String; NewTimestamp: TDateTime): String;
var
  poiTimeStamp: TDateTime;
  myPOI: TMyPOI;
  Index: Integer;
begin
  if PoiDict.TryGetValue(username, myPOI) then
  begin
    // Обновление существующего объекта
    Result := IntToStr(myPOI.Value) + ' ' + DateTimeToStr(myPOI.Timestamp);
    poiTimestamp := myPOI.Timestamp;
    // Изменение свойства объекта напрямую изменит его в словаре
    myPOI.Timestamp := NewTimeStamp;
  end
  else
  begin
    // Добавление нового объекта
    Index := Random(999);
    Result := IntToStr(Index) + ' ' + DateTimeToStr(NewTimeStamp);
    myPOI := TMyPOI.Create;
    try
      myPOI.Value := Index;
      myPOI.Timestamp := NewTimeStamp;
      PoiDict.Add(username, myPOI);
    except
      on E: Exception do
      begin
        myPOI.Free;
        raise;
      end;
    end;
  end;
end;
initialization
  PoiDict := TObjectDictionary<string, TMyPOI>.Create([doOwnsValues]);
finalization
  PoiDict.Free;

Проверка на исключения

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

Заключение

При работе с коллекциями в Delphi важно понимать, что после добавления объекта в коллекцию, которая поддерживает владение объектами, освобождение этого объекта может привести к утечкам памяти. Использование TObjectDictionary с включенным режимом владения позволяет избежать ручного управления памятью и автоматически освобождает объекты при удалении коллекции.

Создано по материалам из источника по ссылке.

Управление памятью в Delphi при работе со словарями объектов требует внимательного обращения с объектами, чтобы избежать утечек из-за неправильного освобождения ссылок.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Память и Указатели ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-27 11:18:34/0.0062170028686523/0