Форум: "Основная";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
ВнизПроблема с освобождением памяти Найти похожие ветки
← →
Duncan (2004-06-16 15:23) [0]Я создаю список, через некоторое время кидаю его в БД и освобождаю. Но в результате оперативка тает на глазах и не освобождается. Освобождается она только после завершения программы, но т.к. мне нужен сервис, то соответственно постоянно оперативка пожирается при попытке обработать очередной файл. Вот структура и процедура уничтожения списка:
//По горизонтали идет идут данные 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 15:26) [1]В алгоритме куча ошибок.
Например, зачем new(p), если сразу выполняется p:=arrpoint[i];
← →
Duncan (2004-06-16 15:32) [2]Ладно, с эти согласен, но все-равно ведь память должна освобождаться???
Если я пишу
new(p); despose(p);
new(p); despose(p);
то все-равно памяти должно быть столько же сколько было бы если я бы этого не писал или я что-то путаю?
← →
panov © (2004-06-16 15:34) [3]Duncan (16.06.04 15:32) [2]
вот так освобождается:
new(p);
dispose(p);
вот так - нет:
new(p);
p := p1;
dispose(p);
← →
Тимохов © (2004-06-16 15:35) [4]
> Duncan (16.06.04 15:32) [2]
> Ладно, с эти согласен, но все-равно ведь память должна освобождаться???
>
конечно должна.
вы ее берете и не фига не осбобождаете.
одно место вам указали.
второе new(a); a := ...
← →
Duncan (2004-06-16 15:36) [5]2panov
А как тогда правильнее писать? Просто я это в универе проходил давно, но мы там вроде именно так и писали... Заранее спасибо...
← →
Тимохов © (2004-06-16 15:37) [6]
> panov © (16.06.04 15:34) [3]
если конечно случайным образом p1 не было равным p :)))))
← →
Тимохов © (2004-06-16 15:38) [7]
> Duncan (16.06.04 15:36) [5]
в универе вопросы не учат задавать?
> но мы там вроде именно
> так и писали...
что так? как? как panov сказал? тогда о чем вы спрашиваете.
если как вы писали раньше, тогда нафига
> А как тогда правильнее писать
вам же ответили уже
:(((
← →
Sandman25 © (2004-06-16 15:39) [8][5] Duncan (16.06.04 15:36)
А Вам вообще не нужно делать new и dispose, судя по строке p:=arrpoint[i];
← →
panov © (2004-06-16 15:45) [9]>Duncan (16.06.04 15:36) [5]
New и Dispose работает с указателями на определенные участки памяти.
После выполнения New(p) p указывает на участок памяти, выделенный менеджером памяти.
Dispose(p) передает менеджеру памяти указатель на участок памяти, которую желательно освободить. Если p не изменялся, то все в порядке - менеджер памяти находит в своих списках этот адрес и освобождает паямть.
Но если вдруг кто-то присвоит указателю p другой адрес, например p := p1;
То менеджер памяти не сможет найти в списках этот адрес, и память, соответственно, не будет освобождена.
← →
Duncan (2004-06-16 15:49) [10]Ладно упростим задачу. Как мне очистить место которое занимает список?
← →
Sandman25 © (2004-06-16 15:54) [11][10] Duncan (16.06.04 15:49)
А как он его получал?
Если arrpoint: array of tip_a, то вообще не надо ничего освобождать :)
← →
Duncan (2004-06-16 16:02) [12]
p^.next:=arrpoint[tr.ip_b div 16777216];
if (p^.next<>nil) and (p^.next^.IP_B<=tr.IP_B) then begin //Áåãàåì ïî ñïèñêó
p:=p^.next; q:=p;
if p^.IP_B=tr.IP_B then
AddIP_A(p^.down)
else begin
p:=p^.next;
while (p<>nil) do
if p^.IP_B=tr.IP_B then begin
AddIP_A(p^.down); break; end
else if p^.IP_B<tr.IP_B then begin
q:=p; p:=p^.next; end
else begin
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down);
break end;
if (p=nil) then begin
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
end end
else begin //Äîáàâëÿåì IP_B è IP_A
new(q_b); q_b^.next:=p^.next; q_b^.IP_B:=tr.IP_B;
arrpoint[tr.ip_b div 16777216]:=q_b;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
p:=nil;
← →
Duncan (2004-06-16 16:03) [13]
p^.next:=arrpoint[tr.ip_b div 16777216];
if (p^.next<>nil) and (p^.next^.IP_B<=tr.IP_B) then begin //Áåãàåì ïî ñïèñêó
p:=p^.next; q:=p;
if p^.IP_B=tr.IP_B then
AddIP_A(p^.down)
else begin
p:=p^.next;
while (p<>nil) do
if p^.IP_B=tr.IP_B then begin
AddIP_A(p^.down); break; end
else if p^.IP_B<tr.IP_B then begin
q:=p; p:=p^.next; end
else begin
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down);
break end;
if (p=nil) then begin
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
end end
else begin //Äîáàâëÿåì IP_B è IP_A
new(q_b); q_b^.next:=p^.next; q_b^.IP_B:=tr.IP_B;
arrpoint[tr.ip_b div 16777216]:=q_b;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
p:=nil;
← →
Sandman25 © (2004-06-16 16:05) [14]ИМХО проще всего перед arrpoint[i] := nil; поставить dispose(arrpoint[i])
← →
Duncan (2004-06-16 16:07) [15]>Sandman25 © (16.06.04 16:05) [14]
А остальные элементы освободят память?
← →
Sandman25 © (2004-06-16 16:13) [16]А у Вас же там цикл по всем элементам arrpoints...
← →
Duncan (2004-06-16 16:17) [17]Sandman25 © (16.06.04 16:13) [16]
По ним то понятно, а вот внутри у меня еще 2 цикла по p и по а, вот память которую они занимают как можно освободить?
← →
Duncan (2004-06-16 16:22) [18]ИМХО проще всего перед arrpoint[i] := nil; поставить dispose(arrpoint[i])
Так делать точно нельзя, потому как после dispose(arrpoint[i]), к arrpoint[i] обращаться нельзя, Дельфя ругнется типа "Inaccessable value"
← →
Sandman25 © (2004-06-16 16:22) [19]Если в arrpoints хранятся только начала списков (мне лень было разбираться, честно говоря), то, конечно, нужно пробежаться по списку и освободиться все его элементы.
← →
Duncan (2004-06-16 16:25) [20]Если в arrpoints хранятся только начала списков (мне лень было разбираться, честно говоря), то, конечно, нужно пробежаться по списку и освободиться все его элементы.
Да ты совершенно прав, но КАК освободить элементы этого списка. Вот я ошибочно полагал, что диспоус освобождает память на которую указывает переменная.
← →
Sandman25 © (2004-06-16 16:29) [21]p := arr[i];
while p <> nil do
begin
p1 := p.next;
dispose(p);
p := p1;
end;
← →
Duncan (2004-06-16 17:11) [22]Написал процедуру следующим образом, но ничего не помогает, память по прежнему расходуется.
procedure SaveAndDestroy;
var
i, count:integer;
p,p1:PTIP_B;
a,a1:PTIP_A;
begin
wtr.StartTransaction;
for i:=0 to 255 do begin
p:=arrpoint[i];
while (p<>nil) do begin
a:=p^.down;
while (a<>nil) do begin
with qIns do begin
ParamByName("IP_A").AsInt64:=a^.IP_A; ParamByName("IP_B").AsInt64:=p^.IP_B;
ParamByName("ASN_A").AsInteger:=a^.ASN_A; ParamByName("ASN_B").AsInteger:=a^.ASN_B;
ParamByName("INT_A").AsInteger:=a^.INT_A; ParamByName("INT_B").AsInteger:=a^.INT_B;
ParamByName("BYTES_A").AsInt64:=a^.BYTES_A; ParamByName("BYTES_B").AsInt64:=a^.BYTES_B;
ParamByName("DT").AsDateTime:=a^.DT; ExecQuery end;
inc(count);
if count>700 then begin
wtr.Commit; count:=count-700;
wtr.StartTransaction; end;
a1:=a^.down; dispose(a);
a:=a1; end;
p1:=p^.next; dispose(p);
p:=p1; end;
arrpoint[i]:=nil; end;
wtr.Commit;
end;
← →
Sandman25 © (2004-06-16 17:18) [23][22] Duncan (16.06.04 17:11)
Вроде все правильно, насколько я понимаю. Может, где-то еще память выделяется.
← →
Digitman © (2004-06-16 17:33) [24]
> Duncan (16.06.04 15:36) [5]
Просто я это в универе проходил
> .., но мы там вроде именно так и писали
если ты в "универе" не постиг банальной истины а-ля
New(P);
//до момента Dispose() не трожь кривыми руками указательную переменную Р ! И неважно, цикл или не цикл !
....
Dispose(Р);
← →
Duncan (2004-06-17 13:40) [25]Digitman © (16.06.04 17:33) [24]
Спасибо, мне это итак уже здесь разжували ...
Но вот только никто толком не смог мне сказать как память списка очистить. А если Вы считаете что я тупой, то будьте любезны потратьте 5-7 минут и модифицируйте мой неправильный код в более верный.
procedure SaveAndDestroy;
var
i:integer;
p,p1:PTIP_B;
a,a1:PTIP_A;
begin
for i:=0 to 255 do begin
p:=arrpoint[i];
while (p<>nil) do begin
a:=p^.down;
while (a<>nil) do begin
a1:=a^.down;
dispose(a);
a:=a1;
end;
p1:=p^.next;
dispose(p);
p:=p1;
end;
arrpoint[i]:=nil; end;
end;
С уважением, Анатолий!
P.S. Заранее огромное спасибо!
← →
Тимохов © (2004-06-17 13:51) [26]
> С уважением, Анатолий!
сомневаюсь
← →
Тимохов © (2004-06-17 13:52) [27]
> Duncan (17.06.04 13:40) [25]
судя по всему ошибка в другом месте
← →
Duncan (2004-06-17 14:01) [28]Тимохов © (17.06.04 13:52) [27]
Я ужастно дико извиняюсь, понимаю что всех уже достал тут, но очень надо. Причем я уверен, что проблема именно в этом месте. Могу прислать исходники если они помогут, хотя они написаны опять таки в стиле удобном мне для чтения.
← →
Тимохов © (2004-06-17 14:13) [29]
> Причем я уверен, что проблема именно в этом месте.
зря уверены. в самом коде ничего криминального нет.
я тоже уверен.
смотрите внимательнее как вы создаете arrpoint. проверьте глазами соответствует ли логика освобождения массива логике заполнения массива?
← →
Duncan (2004-06-17 14:21) [30]В том то все и дело, что в массиве arrpoint храняться так называемые головы (head) списков. Их всего 256 штук. Соответственно каждый из них указывает на элемент типа PTIP_B.
Единственное что массив описан так: ArrPoint: array [0..255] of Pointer;
При этом если бы они только не освобождались то потерялось бы не так много памяти.
Вообщем если есть возможность и желание давай пообщаемся в аське 24753812.
← →
Тимохов © (2004-06-17 14:28) [31]
> Вообщем если есть возможность и желание давай пообщаемся
> в аське 24753812.
аська у меня закрыта.
Вообще-то это не совсем список. Не знаю как по науке это назвается, я бы назвал двумерный список.
Я вряд ли тебе помогу - надо копать остальные исходники, а на это времени нет :(
Еще раз говорю - проверьте логику заполнения списка. Она должно соответствовать логике освобожденя списка. С учетом того, что в первоначальном вашем методе была масса ошибок - думаю при заполнении списка их не меньше.
← →
Duncan (2004-06-17 14:39) [32]Ну вот так у меня все это дело формируется:
p^.next:=arrpoint[tr.ip_b div 16777216];
if (p^.next<>nil) and (p^.next^.IP_B<=tr.IP_B) then begin //Если список не пуст
p:=p^.next; q:=p;
if p^.IP_B=tr.IP_B then AddIP_A(p^.down) //Добавляем ветку вниз
else begin
p:=p^.next;
while (p<>nil) do //Идем горизонтально по списку
if p^.IP_B=tr.IP_B then begin
AddIP_A(p^.down); break; //Нашелся одинаковый элемент, добавляем ветку вниз
end
else if p^.IP_B<tr.IP_B then begin
q:=p; p:=p^.next; //Пока значение меньше переходим дальше по списку
end
else begin //иначе вставляем элемент между предыдущим (q) и текущим элементом (p)
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down);
break end;
if (p=nil) then begin //Если конец списка
new(q_b); q_b^.next:=p;
q^.next:=q_b; q_b^.IP_B:=tr.IP_B;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
end end
else begin //Либо пустой список, либо после головы списка вставлять надо
new(q_b); q_b^.next:=p^.next; q_b^.IP_B:=tr.IP_B;
arrpoint[tr.ip_b div 16777216]:=q_b;
q_b^.down:=nil; AddIP_A(q_b^.down); end;
p:=nil;
← →
Sandman25 © (2004-06-17 14:49) [33][32] Duncan (17.06.04 14:39)
Это тоже вроде правильно, за исключением многократного дублирования, усложняющего понимание и поиск ошибок. А в AddIP_A что делается?
← →
Duncan (2004-06-17 14:57) [34]Аналогично только добавляется ветка вниз:
procedure AddIP_A(var d1:PTIP_A);
var q_a,d,q:PTIP_A;
l:integer;
begin
new(q_a); new(d); new(q);
d:=q; l:=0;
if (d1=nil) or (d1^.IP_A>tr.IP_A) then begin //Если список пуст или надо добавить в начале
q_a^.down:=d1; d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT end
else begin
q:=d1;
while (q<>nil) do begin //Пока не конец
l:=l+1; //Отслеживаем уровень
if q^.IP_A<tr.IP_A then begin d:=q; q:=Q^.down; end //Спускаемся вниз
else if q^.IP_A>tr.IP_A then begin //иначе добавляем
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break
end //Дальше аналогично только для других параметров
else if q^.INT_A<tr.INT_A then begin d:=q; q:=Q^.down; end
else if q^.INT_A>tr.INT_A then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else if q^.INT_B<tr.INT_B then begin d:=q; q:=Q^.down; end
else if q^.INT_B>tr.INT_B then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else if q^.ASN_A<tr.ASN_A then begin d:=q; q:=Q^.down; end
else if q^.ASN_A>tr.ASN_A then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break; end
else if q^.ASN_B<tr.ASN_B then begin d:=q; q:=Q^.down; end
else if q^.ASN_B>tr.ASN_B then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else begin
q^.BYTES_A:=q^.BYTES_A+tr.BYTES_A;
q^.BYTES_B:=q^.BYTES_B+tr.BYTES_B;
break end; end;
if (q=nil) then begin //Если мы дошли до конца списка
q_a^.down:=q; d^.down:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT end
end
end;
← →
Sandman25 © (2004-06-17 14:59) [35]Ну вот, Вам же говорили про ошибку в другом месте :)
new(q_a); new(d); new(q);
d:=q; l:=0;
и как Вы после этого собираетесь освобождать память, занятую при new(q)?
← →
Sandman25 © (2004-06-17 15:01) [36]То есть new(d)
← →
Duncan (2004-06-17 15:24) [37]Ну да лоханулся, поменял на следующий вид, но ничего не изменилось
procedure AddIP_A(var d1:PTIP_A);
var q_a,d,q:PTIP_A;
l:integer;
begin
l:=0; new(q_a);
if (d1=nil) or (d1^.IP_A>tr.IP_A) then begin
q_a^.down:=d1; d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT end
else begin
q:=d1; d:=q;
while (q<>nil) do begin
l:=l+1;
if q^.IP_A<tr.IP_A then begin d:=q; q:=Q^.down; end
else if q^.IP_A>tr.IP_A then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else if q^.INT_A<tr.INT_A then begin d:=q; q:=Q^.down; end
else if q^.INT_A>tr.INT_A then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else if q^.INT_B<tr.INT_B then begin d:=q; q:=Q^.down; end
else if q^.INT_B>tr.INT_B then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else if q^.ASN_A<tr.ASN_A then begin d:=q; q:=Q^.down; end
else if q^.ASN_A>tr.ASN_A then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break; end
else if q^.ASN_B<tr.ASN_B then begin d:=q; q:=Q^.down; end
else if q^.ASN_B>tr.ASN_B then begin
q_a^.down:=q;
if l>1 then d^.down:=q_a else d1:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT;
break end
else begin
q^.BYTES_A:=q^.BYTES_A+tr.BYTES_A;
q^.BYTES_B:=q^.BYTES_B+tr.BYTES_B;
dispose(q_a);
break end; end;
if (q=nil) then begin
q_a^.down:=q; d^.down:=q_a;
q_a^.IP_A:=tr.IP_A; q_a^.INT_A:=tr.INT_A;
q_a^.int_B:=tr.INT_B; q_a^.ASN_A:=tr.ASN_A; q_a^.ASN_B:=tr.ASN_B;
q_a^.BYTES_A:=tr.BYTES_A; q_a^.BYTES_B:=tr.BYTES_B; q_a^.DT:=tr.DT end
end
end;
← →
Sandman25 © (2004-06-17 15:46) [38][37] Duncan (17.06.04 15:24)
а вот дальше уже самостоятельно. Может эта мука с отладкой заставит Вас использовать процедуры вместо копирования кусков кода.
← →
Duncan (2004-06-17 16:00) [39]Sandman25 © (17.06.04 15:46) [38]
Может и заставит :) Но такие механические действия не должны влиять на логику работы с памятью :( Вообщем буду еще как-то пытаться ковырять эту лабуду.
← →
Duncan (2004-06-17 16:06) [40]Спасибо всем кто пытался помочь.
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.034 c