type
TTestClass = class
public
v_strmus: TStringDynArray;
v_intmus: array of integer;
v_obj_strlis : TStringList;
Constructor Create;
Destructor Destroy; override;
end;
TTestClass.Create()
begin
inherited;
v_obj_strlis := TStringList.Create;
end;
TTestClass.Destroy()
begin
FreeAndNil( v_obj_strlis );
inherited;
end;
Про память
Код:
Вопрос собственно:
1. Обязательно в деструкторе нужно явно удалить v_obj_strlis, иначе, когда я удалю объект класса TTestClass память занятая v_obj_strlis не освободится (ведь так)?
2. Нужно ли в деструкторе очищать память занимаемую массивами v_strmus и v_intmus? То есть если в деструкторе явно не писать SetLength( v_strmus , 0), SetLength( v_intmus , 0), то останется ли память занимаемая этими массивами (ведь фактически они динамические и память сама не очиститься??)?
2. Динамические массивы освобождаются компилятором (тобишь он код для этого генерит).
Здесь по аналогии с обычной процедурой:
объект
Код:
Obj := TObj.Create;
try
...
finally
Obj.Free;
end;
try
...
finally
Obj.Free;
end;
д.массив:
Код:
a: array of []
begin
SetLength(a, ...)
...
end;
begin
SetLength(a, ...)
...
end;
Если дин. массив объектов, их нужно освобождать явно, в деструкторе.
Цитата: Phodopus
2. Динамические массивы освобождаются компилятором (тобишь он код для этого генерит).
Не совсем верно. Для динамических массивов (как и для строк и интерфейсов) предусмотрено управление памятью на основе подсчета ссылок.
Цитата: hardcase
Не совсем верно. Для динамических массивов (как и для строк и интерфейсов) предусмотрено управление памятью на основе подсчета ссылок.
Так и я о том же :)
Что компилятор сам генерит невидимый нам эпилог функции типа
Код:
...
a.refcnt := a.refcnt - 1;
if a.refcnt = 0 then FreeDynArray(a);
a.refcnt := a.refcnt - 1;
if a.refcnt = 0 then FreeDynArray(a);
для функций эпилог в ее конце, для классов - в деструкторе.