Главная » Delphi » Варианты  — объекты  с управляемым временем жизни

0

Delphi  автоматически выделяет и освобождает память  для данных  типа  Variant. Рассмотрим приведенный ниже пример, в котором варианту присваивается строка.

procedure ShowVariant(S: string);

var

V: Variant

begin

V := S;

ShowMessage(V);

end;Как уже отмечалось в этой  главе,  в отношении объектов с управляемым временем жизни, при выполнении программы осуществляется несколько действий, которые не вполне очевидны. Прежде всего  Delphi инициализирует вариант пустым  значением. Затем, в ходе присвоения значения, в поле VType помещается значение varString, а в поле  VString копируется указатель  на строку.  При  этом  счетчик ссылок  строки S увеличивается. Когда  вариант покидает область  видимости (в  данном  случае —  при выходе  из процедуры), он удаляется  и счетчик ссылок  строки S уменьшается. Delphi реализует это, помещая тело процедуры в блок try..finally, как показано ниже.

procedure ShowVariant(S: string);

var

V: Variant

begin

V := Unassigned;       // Инициализирует вариант как "пустой"

try

V := S;

ShowMessage(V);

finally

// Теперь можно освободить ресурсы, связанные с вариантом

end;

end;

Точно такое  же  неявное освобождение ресурсов происходит и при  присвоении варианту данных нового типа. Рассмотрим следующий пример:

procedure ChangeVariant(S: string);

var

V: Variant

begin

V := S;

V := 34;

end;

Данный код сводится к приведенному ниже псевдокоду:

procedure ChangeVariant(S: string);

var

V: Variant

begin

Освободить вариант V, инициализировав его как "пустой"

try

V.VType := varString; V.VString := S; Inc(S.RefCount); Освободить вариант V, сославшись на другие данные; V.VType := varInteger; V.VInteger := 34;

finally

Освободить ресурсы, связанные с вариантом

end;

end;

Разобравшись в работе этого  примера, можно  понять, почему  не  рекомендуется непосредственно манипулировать полями записи  TVarData, как в данном случае:

procedure ChangeVariant(S: string);

varV: Variant begin

V := S;

TVarData(V).VType := varInteger;

TVarData(V).VInteger := 32;

V := 34;

end;

Хотя все кажется вполне корректным, это далеко не так — ведь уменьшение счетчика ссылок строки S не выполняется, что приводит к утечке памяти. Одним словом,  никогда не работайте с полями TVarData напрямую, а если  все же приходится делать  это,  то следует четко  понимать, что именно происходит и к каким последствиям это может привести.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии