Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.07.29;
Скачать: CL | DM;

Вниз

Проблемы с памятью   Найти похожие ветки 

 
Sventitskiy ©   (2007-07-02 17:38) [0]

Добрый день.

У меня следующий вопрос. Имеется динамический массив DArray: array of TIntResultObjected, элементами которого являются записи:

TIntResultObjected=record              
WaveLength: real;          
Results: TList;          
end;

Элементы списка (поле Results) тоже записи вида:

TResultObjectedData=record
X,Y,Z: real;                        
Value_WaveLength: real;  
end;

Программа производит расчет и создает массив. Потом при повторении расчета массив должен уничтожаться а память должна соотв. освобождаться. Я делаю это как:

DArray:=Nil;

Но похоже что этого не достаточно, так как после нескольких расчетов Windows выдает сообщение Out of memory.

Как корректно освободить память?

С уважением,
Александр


 
авыф   (2007-07-02 17:40) [1]

SetLength(...,0)?


 
Desdechado ©   (2007-07-02 17:42) [2]

Пройтись по массиву и Results.Free для каждого элемента.


 
Loginov Dmitry ©   (2007-07-02 22:41) [3]

> TIntResultObjected=record              
> WaveLength: real;          
> Results: TList;          
> end;


Тут очевидно, уже не запись, а class напрашивается


 
Sventitskiy ©   (2007-07-03 00:50) [4]

Возможно напрашивается Class но сделано так и нет времени переделывать.
Как все-таки сделать с записью. Проход по массиву и Results.Free для каждого элемента не помогает!!!


 
Юрий Зотов ©   (2007-07-03 01:10) [5]

Элементы списка TResultObjectedData, по-видимому, тоже создаются в хипе - значит, эту память тоже надо освобождать.


 
Германн ©   (2007-07-03 01:14) [6]


> Как все-таки сделать с записью. Проход по массиву и Results.
> Free для каждого элемента не помогает!!!

А какое Free может быть для записи?


 
icWasya ©   (2007-07-03 10:24) [7]

У вас в коде наверняка есть вот такие строки

SetLength(DArray,Length(DArray)+1);

если вызывать такой код много раз, то будет жуткая фрагментация памяти, что в конце концов приведёт к  Out of memory.
Решение - Перераспределять памать в DArray большими блоками,
Не использовать Length(DArray) для указания количества используемых элементов массива, а завести для этого специальную переменную.
например так

var
 DArray: array of TIntResultObjected;
 LenArray:Integer;

procedure AddToDArray;
begin
 Inc(LenArray);
 if LenArray>=Length(DArray) then SetLength(DArray,LenArray+100);//или сколько там
 DArray[LenArray-1].Results:=TList.Create;
end;

procedure ClearDArray;
var
 I:Integer;
begin
 for I:= 0 to LenArray-1 do;
 DArray[I].Results.Free;
 LenArray:=0;
 // SetLength(DArray,0);
end;


 
SlymRO ©   (2007-07-03 10:35) [8]

icWasya ©   (03.07.07 10:24) [7]
Не проще:
TResultObjectedData=record
 X,Y,Z:real;                        
 Value_WaveLength:real;  
end;
TIntResultObjected=record
 WaveLength: real;
 Results:array of TResultObjectedData;
end;

само собой убьется...


 
Desdechado ©   (2007-07-03 10:55) [9]

> А какое Free может быть для записи?
Results: TList;


 
Anatoly Podgoretsky ©   (2007-07-03 12:29) [10]

Как создавал TResultObjectedData=record
так и уничтожай, естественно в цикле


 
Sapersky   (2007-07-03 14:24) [11]

procedure AddToDArray;

Тогда уж так (несколько длинновато, зато универсально):

{$IFDEF DELPHI4or5}
Type
 PDynArrayTypeInfo = ^TDynArrayTypeInfo;
 TDynArrayTypeInfo = packed record
   kind: Byte;
   name: string[0];
   elSize: Longint;
   elType: ^PDynArrayTypeInfo;
   varType: Integer;
 end;

procedure DynArraySetLength(var a: Pointer; typeInfo: PDynArrayTypeInfo; dimCnt: Longint; lengthVec: PLongint);
asm
 push edi
 push esi
 push ebx
 mov esi, lengthVec
 mov ebx, ecx
@loop: // first we must push all lengthVec in the stack
 mov edi,[esi]
 push edi
 add esi, 4
 dec ebx
 jnz @loop
 mov ebx, ecx

 call system.@DynArraySetLength

 imul ebx, $04
 add esp, ebx // restoring stack (works like pop)
 pop ebx
 pop esi
 pop edi
end;
{$ENDIF}

// note: if elements are dynarrays, only references are copied
// with ref count increment (DynArrayAsg)
procedure Arr_Copy( Dst, Src : Pointer; Info: PTypeInfo; Cnt: Integer);
asm
 push Cnt
 CALL    System.@CopyArray;
//  add esp, 4 // for some reason we don"t need stack restoring
end;

// mostly the same as SetLength, but reallocates array with blocks in TList style
// Length(Arr) plays role of Capacity here,
// so you must keep used array size in separate variable (pass it to NewCount)
procedure Arr_Grow(Var Arr; TypInfo: PDynArrayTypeInfo; NewCount : Integer);
Var Len, Capacity : Integer;
begin
Assert(TypInfo.Kind = Byte(tkDynArray), "Arr_Grow: Only dynamic arrays supported");
If (Pointer(Arr) <> nil) then begin
 Len := PInteger(Integer(Arr) - SizeOf(Integer))^;
 If (NewCount <= Len) then Exit; // we fit to existing capacity, no need to grow  
 Capacity := Len * 2; // not sure this will be always best way...
 If Capacity < NewCount then Capacity := NewCount;
end else
 Capacity := NewCount; // was no array - just allocate NewCount elements

DynArraySetLength(Pointer(Arr), TypInfo, 1, @Capacity);
end;

function Arr_AddItem(Var Arr; TypInfo: PDynArrayTypeInfo; Var Count : Integer;
                    Src: PByte = nil; AtPos : Integer = -1): Pointer;
Var Dst : PByte;
   ElSize : Integer;
begin
Arr_Grow(Arr, TypInfo, Count + 1);
Inc(PByte(TypInfo), Length(TypInfo.Name)); ElSize := TypInfo.elSize;
Dst := PByte(Arr);
If (AtPos >= 0) and (AtPos < Count) then begin
 Inc(Dst, AtPos * ElSize);
 Move(Dst^, PByte( Integer(Dst) + ElSize )^, ElSize * (Count - AtPos));
 If (TypInfo.elType <> nil) then FillChar(Dst^, ElSize, 0);
end else
 Inc(Dst, Count * ElSize);
Result := Dst;
If (Src <> nil) then
 If TypInfo.elType <> nil then Arr_Copy(Dst, Src, PTypeInfo(TypInfo.elType^), 1)
                          else Move(Src^, Dst^, TypInfo.elSize);
Inc(Count);
end;

TypInfo добывается как TypeInfo(<тип массива>).



Страницы: 1 вся ветка

Текущий архив: 2007.07.29;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.026 c
11-1166279345
NeeDiGeo
2006-12-16 17:29
2007.07.29
Добавление формы в уже существующий проект KOL_MCK


15-1183367376
Углук
2007-07-02 13:09
2007.07.29
Delphi Russian Knowledge Base


8-1161870623
Gamer
2006-10-26 17:50
2007.07.29
Рисование графиков


15-1183515466
Slider007
2007-07-04 06:17
2007.07.29
С днем рождения ! 4 июля 2007 среда


15-1183226565
IPE
2007-06-30 22:02
2007.07.29
ColdFusion &amp; Dreamweaver