Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Finalize array of array of Integer  [new]
Квейд
Member

Откуда: Kyiv, Ukraine
Сообщений: 5077
Синтетический пример, по которому есть вопрос:

procedure DoSome;
var
  A: array of array of Integer;
  I: Integer;
begin
// создаем массив, напоминающий гребешок с разной длиной зубцов
  SetLength(A, 3);
  for I := 0 to 2 do
    SetLength(A[I], Random(10));
//...
  Finalize(A); // Вопрос: финализнется ли весь "гребешок" или по каждому "зубу" надо делать отдельный Finalize?
//...
end;


When a movie is over, it's a black
2 окт 18, 16:38    [21692962]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10578
Квейд,

Будет финализироваться весь массив. Но здесь финализация не нужна. Все финализируется само. Явная финализация нужна при работе с указателями на типы с управляемым временем жизни. Тут этого нет
2 окт 18, 16:45    [21692980]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
Квейд
Member

Откуда: Kyiv, Ukraine
Сообщений: 5077
_Vasilisk_
Квейд,

Будет финализироваться весь массив. Но здесь финализация не нужна. Все финализируется само. Явная финализация нужна при работе с указателями на типы с управляемым временем жизни. Тут этого нет


Дело в том, что по-факту моя процедура рекурсивная, то есть если я не финализирую массив А перед следующим рекурсивным вызовом DoDome, то массив A будет существовать и иметь свой экземпляр для каждого звена во всей цепочке рекурсии, чего я как раз пытаюсь избежать.

procedure DoSome;
var
  A: array of array of Integer;
  I: Integer;
begin
  SetLength(A, 3);
  for I := 0 to 2 do
    SetLength(A[I], Random(10));
//...
  Finalize(A); если этого не сделать здесь, то массив будет существовать отдельно для каждого рекурсивного вызова, разве нет?
//…
  DoSome;
//…

end;
2 окт 18, 16:55    [21692999]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10578
Квейд
будет существовать и иметь свой экземпляр для каждого звена во всей цепочке рекурсии
Не факт. Оптимизатор может грохнуть переменную как только увидит, что она нигде не используется.

Если хочешь все контролировать явно, то, имхо, проще вызвать
SetLength(A, 0);
2 окт 18, 17:14    [21693021]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
Квейд
Member

Откуда: Kyiv, Ukraine
Сообщений: 5077
_Vasilisk_
Квейд
будет существовать и иметь свой экземпляр для каждого звена во всей цепочке рекурсии
Не факт. Оптимизатор может грохнуть переменную как только увидит, что она нигде не используется.

Если хочешь все контролировать явно, то, имхо, проще вызвать
SetLength(A, 0);
По идее, управляемые типы вроде массивов грохаются, когда выходят за пределы области видимости
2 окт 18, 17:40    [21693051]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10578
Квейд
управляемые типы вроде массивов грохаются, когда выходят за пределы области видимости
Это гарантировано. Но оптимизатор может их прибить когда они больше не нужны. А может и не прибить
2 окт 18, 17:54    [21693073]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
Finalize
Guest
Finalize пройдётся по каждому из выделенных элементов массива, уничтожив все выделенные массивы внутри.


это легко проверить, взяв указатель на выделенный элемент, и после Finalize попытаться обратится по указателю.
2 окт 18, 18:41    [21693139]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
delphinotes
Member

Откуда: Санкт-Петербург
Сообщений: 296
Квейд,

Зайди в процедуру под отладчиком, открой CPU Window (Ctrl+Alt+C) и увидишь вызов .. что-то там типа DynArrayClear. Это должно дать ответы на все вопросы.
2 окт 18, 21:19    [21693358]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
Василий 2
Member

Откуда:
Сообщений: 205
_Vasilisk_
Квейд
управляемые типы вроде массивов грохаются, когда выходят за пределы области видимости
Это гарантировано. Но оптимизатор может их прибить когда они больше не нужны. А может и не прибить

Оптимизатор не настолько умный. Видя переменные managed типа, он тупо оборачивает весь код в блок try-finally, где в finally секции очищает все переменные.
8 окт 18, 17:21    [21698428]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
AX-Class
Member

Откуда:
Сообщений: 127
При выходе из зоны видимости все очистится. Но надо понимать ситуации, когда зона видимости не работает.
procedure TForm1.Button1Click(Sender: TObject);
type
 TArr = array of array of Integer;
  TRecord = Record
    A: TArr;
  end;
var
  A: TArr;
  I: Integer;
  recPointer : ^TRecord;
begin
  ReportMemoryLeaksOnShutdown := True;
// создаем массив, напоминающий гребешок с разной длиной зубцов
  SetLength(A, 3);
  for I := 0 to 2 do
    SetLength(A[I], Random(10));
  GetMem(recPointer, SizeOf(TRecord));
  recPointer.A := A;
//...
  Finalize(A); // Вопрос: финализнется ли весь "гребешок" или по каждому "зубу" надо делать отдельный Finalize?
  Finalize(recPointer^);  // <-- если убрать, то потечём
  //...
  FreeMem(recPointer);
end;
10 окт 18, 02:09    [21699954]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
jmp_original
Guest
AX-Class, зона видимости тут совершенно ни при чём. О чём чётко написано в хэлпе.
10 окт 18, 08:40    [21700047]     Ответить | Цитировать Сообщить модератору
 Re: Finalize array of array of Integer  [new]
alekcvp
Member

Откуда:
Сообщений: 1104
AX-Class,

Ну если неправильно работать с памятью, то да, потечёт.

procedure TForm1.Button1Click(Sender: TObject);
type
 TArr = array of array of Integer;
  TRecord = Record
    A: TArr;
  end;
var
  A: TArr;
  I: Integer;
  recPointer : ^TRecord;
begin
  ReportMemoryLeaksOnShutdown := True;
// создаем массив, напоминающий гребешок с разной длиной зубцов
  SetLength(A, 3);
  for I := 0 to 2 do
    SetLength(A[I], Random(10));
// --- GetMem(recPointer, SizeOf(TRecord));
  New(recPointer);
  recPointer.A := A;
//...
  Finalize(A); // Вопрос: финализнется ли весь "гребешок" или по каждому "зубу" надо делать отдельный Finalize?
// --- Finalize(recPointer^);  // <-- если убрать, то потечём
  //...
// ---  FreeMem(recPointer);
  Dispose(recPointer);
end;

Как бы всегда для типизированных указателей применялось New() и Dispose(). Они и размер сами нужный выделят и Finalize при необходимости сделают.
10 окт 18, 11:06    [21700178]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить