![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с освобождением памяти [D5, Win2k]
Duncan © (2004-06-16 15:23:00)Я создаю список, через некоторое время кидаю его в БД и освобождаю. Но в результате оперативка тает на глазах и не освобождается. Освобождается она только после завершения программы, но т.к. мне нужен сервис, то соответственно постоянно оперативка пожирается при попытке обработать очередной файл. Вот структура и процедура уничтожения списка:
//По горизонтали идет идут данные PTIP_B, для каждого из которого в низ идут данные типа PTIP_A.
type Traf=record
IP_A, IP_B:longword;
ASN_A, ASN_B, INT_A, INT_B:word;
BYTES_A, BYTES_B: longword;
DT: TDateTime;
end;
PTIP_A=^TIP_A;
TIP_A=record
down:PTIP_A;
IP_A:longword;
INT_A, int_B, ASN_A, ASN_B:word;
BYTES_A, BYTES_B: longword;
DT: TDateTime;
end;
PTIP_B=^TIP_B;
TIP_B=record
next:PTIP_B;
down:PTIP_A;
IP_B:longword;
end;
procedure SaveAndDestroy;
var
i, count:integer;
p,p1:PTIP_B;
a,a1:PTIP_A;
begin
new(p);
wtr.StartTransaction;
for i:=0 to 255 do begin
p:=arrpoint[i];
while (p<>nil) do begin
new(a); a:=p^.down;
while (a<>nil) do begin
with qIns do begin
//Пишем в бд
end;
inc(count);
if count>700 then begin
wtr.Commit; count:=count-700;
wtr.StartTransaction; end;
new(a1); a1:=a;
a:=a^.down; dispose(a1);
end;
dispose(a); new(p1);
p1:=p; p:=p^.next; dispose(p1); end;
arrpoint[i]:=nil; end;
wtr.Commit;
dispose(p);
end;
Sandman25 (2004-06-16 16:29:00) [21]p := arr[i];
while p <> nil do
begin
p1 := p.next;
dispose(p);
p := p1;
end;
Duncan (2004-06-16 16:25:00) [22]Если в arrpoints хранятся только начала списков (мне лень было разбираться, честно говоря), то, конечно, нужно пробежаться по списку и освободиться все его элементы.
Да ты совершенно прав, но КАК освободить элементы этого списка. Вот я ошибочно полагал, что диспоус освобождает память на которую указывает переменная.
Sandman25 (2004-06-16 16:22:00) [23]Если в arrpoints хранятся только начала списков (мне лень было разбираться, честно говоря), то, конечно, нужно пробежаться по списку и освободиться все его элементы.
Duncan (2004-06-16 16:22:00) [24]ИМХО проще всего перед arrpoint[i] := nil; поставить dispose(arrpoint[i])
Так делать точно нельзя, потому как после dispose(arrpoint[i]), к arrpoint[i] обращаться нельзя, Дельфя ругнется типа "Inaccessable value"
Duncan (2004-06-16 16:17:00) [25]Sandman25 © (16.06.04 16:13) [16]
По ним то понятно, а вот внутри у меня еще 2 цикла по p и по а, вот память которую они занимают как можно освободить?
Sandman25 (2004-06-16 16:13:00) [26]А у Вас же там цикл по всем элементам arrpoints...
Duncan (2004-06-16 16:07:00) [27]>Sandman25 © (16.06.04 16:05) [14]
А остальные элементы освободят память?
Sandman25 (2004-06-16 16:05:00) [28]ИМХО проще всего перед arrpoint[i] := nil; поставить dispose(arrpoint[i])
Duncan (2004-06-16 16:03:00) [29]
p^.next:=arrpoint[tr.ip_b div 16777216];
if (p^.nextnil) and (p^.next^.IP_B
Duncan (2004-06-16 16:02:00) [30]
p^.next:=arrpoint[tr.ip_b div 16777216];
if (p^.nextnil) and (p^.next^.IP_B
Sandman25 (2004-06-16 15:54:00) [31][10] Duncan (16.06.04 15:49)
А как он его получал?
Если arrpoint: array of tip_a, то вообще не надо ничего освобождать :)
Duncan (2004-06-16 15:49:00) [32]Ладно упростим задачу. Как мне очистить место которое занимает список?
panov (2004-06-16 15:45:00) [33]>Duncan (16.06.04 15:36) [5]
New и Dispose работает с указателями на определенные участки памяти.
После выполнения New(p) p указывает на участок памяти, выделенный менеджером памяти.
Dispose(p) передает менеджеру памяти указатель на участок памяти, которую желательно освободить. Если p не изменялся, то все в порядке - менеджер памяти находит в своих списках этот адрес и освобождает паямть.
Но если вдруг кто-то присвоит указателю p другой адрес, например p := p1;
То менеджер памяти не сможет найти в списках этот адрес, и память, соответственно, не будет освобождена.
Sandman25 (2004-06-16 15:39:00) [34][5] Duncan (16.06.04 15:36)
А Вам вообще не нужно делать new и dispose, судя по строке p:=arrpoint[i];
Тимохов (2004-06-16 15:38:00) [35]
> Duncan (16.06.04 15:36) [5]
в универе вопросы не учат задавать?
> но мы там вроде именно
> так и писали...
что так? как? как panov сказал? тогда о чем вы спрашиваете.
если как вы писали раньше, тогда нафига
> А как тогда правильнее писать
вам же ответили уже
:(((
Тимохов (2004-06-16 15:37:00) [36]
> panov © (16.06.04 15:34) [3]
если конечно случайным образом p1 не было равным p :)))))
Duncan (2004-06-16 15:36:00) [37]2panov
А как тогда правильнее писать? Просто я это в универе проходил давно, но мы там вроде именно так и писали... Заранее спасибо...
Тимохов (2004-06-16 15:35:00) [38]
> Duncan (16.06.04 15:32) [2]
> Ладно, с эти согласен, но все-равно ведь память должна освобождаться???
>
конечно должна.
вы ее берете и не фига не осбобождаете.
одно место вам указали.
второе new(a); a := ...
panov (2004-06-16 15:34:00) [39]Duncan (16.06.04 15:32) [2]
вот так освобождается:
new(p);
dispose(p);
вот так - нет:
new(p);
p := p1;
dispose(p);
Duncan (2004-06-16 15:32:00) [40]Ладно, с эти согласен, но все-равно ведь память должна освобождаться???
Если я пишу
new(p); despose(p);
new(p); despose(p);
то все-равно памяти должно быть столько же сколько было бы если я бы этого не писал или я что-то путаю?