Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Иван Ходов  
Дата: 06.04.02 17:41
Оценка:
Я сделал упрощенный пример, который моделирует мою проблему. Вот две процедуры, которые реагируют на кнопки на форме.
Как Вы легко поймете, первая, с каждым новым кликом, создает массив строк, которым присваивает различную длину.
Вторая должна почистить память.
Но в результате, если нажимать по такой схеме:
12
112
1112
11112
и т.д., т.е. 1-ю кнопку нажимать все больше раз, то происходит все большая утечка памяти примерно по 4-8 Kb.

Расскажите, пожалуйста в чем дело?!?!?!?

type
ptry1=^ttry1;
ttry1=array[1..4096] of string;

TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
t : array of ptry1;
{ Public declarations }
end;


procedure TForm1.Button1Click(Sender: TObject);
var
p : ptry1;
i : longint;
s : String;

begin
new(p);
for i:=1 to 4096 do
Begin
setlength(s,i);
p^[i] := s;
setlength(s,0);
End;
i := length(t);
setlength(t, i+1);
t[i] := p;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i,j: longint;
begin
for i := 0 to length(t)-1 do
Begin
for j := 1 to 4096 do
setlength(t[i]^[j],0);
dispose(t[i]);
End;
t:=nil;
end;

там реальный код сложнее. Этот — просто макет, который производит ту же утечку, что и реальная прога.

Я знаю, что если в первой процедуре на использовать s, а сразу устанавливать длину для элементов массива, то утечки нету. Так в чем проблема? кто знает?
Re: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: AIR Россия  
Дата: 08.04.02 04:21
Оценка:
Здравствуйте Иван Ходов, Вы писали:

ИХ>Я сделал упрощенный пример, который моделирует мою проблему. Вот две процедуры, которые реагируют на кнопки на форме.

ИХ>Как Вы легко поймете, первая, с каждым новым кликом, создает массив строк, которым присваивает различную длину.
ИХ>Вторая должна почистить память.
ИХ>Но в результате, если нажимать по такой схеме:
ИХ>12
ИХ>112
ИХ>1112
ИХ>11112
ИХ>и т.д., т.е. 1-ю кнопку нажимать все больше раз, то происходит все большая утечка памяти примерно по 4-8 Kb.

ИХ>Расскажите, пожалуйста в чем дело?!?!?!?


ИХ>type

ИХ> ptry1=^ttry1;
ИХ> ttry1=array[1..4096] of string;

ИХ>TForm1 = class(TForm)

ИХ> Button1: TButton;
ИХ> Button2: TButton;
ИХ> procedure Button1Click(Sender: TObject);
ИХ> procedure Button2Click(Sender: TObject);
ИХ> private
ИХ> { Private declarations }
ИХ> public
ИХ> t : array of ptry1;
ИХ> { Public declarations }
ИХ> end;


ИХ>procedure TForm1.Button1Click(Sender: TObject);

ИХ>var
ИХ>p : ptry1;
ИХ>i : longint;
ИХ>s : String;

ИХ>begin

ИХ>new(p);
ИХ>for i:=1 to 4096 do
ИХ> Begin
ИХ> setlength(s,i);
ИХ> p^[i] := s;
ИХ> setlength(s,0);
ИХ> End;
ИХ>i := length(t);
ИХ>setlength(t, i+1);
ИХ>t[i] := p;
ИХ>end;

ИХ>procedure TForm1.Button2Click(Sender: TObject);

ИХ>var
ИХ>i,j: longint;
ИХ>begin
ИХ>for i := 0 to length(t)-1 do
ИХ> Begin
ИХ> for j := 1 to 4096 do
ИХ> setlength(t[i]^[j],0);
ИХ> dispose(t[i]);
ИХ> End;
ИХ>t:=nil;
ИХ>end;

ИХ>там реальный код сложнее. Этот — просто макет, который производит ту же утечку, что и реальная прога.


ИХ>Я знаю, что если в первой процедуре на использовать s, а сразу устанавливать длину для элементов массива, то утечки нету. Так в чем проблема? кто знает?

Может я и не прав, но мне кажется следующее. Если все есть так, как ты написал в самом конце пояснения, то у тебя при выходе из первой процедуры не вычищается кусок, ассоциированный с p ( new(p) ). Раз уж ты выделил его сам, то сам и зашибай!!!! ( delete(p) ). А то при выходе указатель созданный на стеке пришибается, а распределенная память не вычищается, ведь автосборщика "мусора" нет!
Безвыходных ситуаций не бывает, это просто такое состояние головного мозга!!!
Re: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Yurik США  
Дата: 09.04.02 20:00
Оценка:
Здравствуйте Иван Ходов, Вы писали:

ИХ>procedure TForm1.Button2Click(Sender: TObject);

ИХ>var
ИХ>i,j: longint;
ИХ>begin
ИХ>for i := 0 to length(t)-1 do
ИХ> Begin
ИХ> for j := 1 to 4096 do
ИХ> setlength(t[i]^[j],0);
ИХ> dispose(t[i]);
ИХ> End;
SetLength(t, 0);
ИХ>t:=nil;
ИХ>end;

Может, поможет. Ты, кстати, как утечки определяешь?
Re[2]: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Аноним  
Дата: 12.04.02 00:13
Оценка:
Неплохо.
Гулял я тут по сайту — думал не плохие тут программеры — прочитал последние два ответа, мнение мое как-то сразу упало.

Ну так как? Не удалось выявить утечку? А то я могу своего друга попросить он может в отладчике посмотреть, как там все это на ассемблерном уровне, может он и выпадет(утечка). :)
Re[3]: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Аноним  
Дата: 12.04.02 02:41
Оценка:
Здравствуйте Аноним, Вы писали:

А>Неплохо.

А>Гулял я тут по сайту — думал не плохие тут программеры — прочитал последние два ответа, мнение мое как-то сразу упало.

А>Ну так как? Не удалось выявить утечку? А то я могу своего друга попросить он может в отладчике посмотреть, как там все это на ассемблерном уровне, может он и выпадет(утечка). :)


Утечку я не нашел, но у меня отпала надобность. Мне никто че-то ничего путного не сказал ни здесь ни на "Мастерах Дельфи", так что я просто переделал алгоритм и переписал код.
Спасибо за предложение, но я не думаю, что твой друг согласится копаться в этом коде. Я сам знаю ассемблер достаточно хорошо, и точно знаю, что мне было бы лень искать утечку на Ассемблерном уровне. Просто в приведенном коде неправильно используется что-то из Дельфей, и я думал, что хоть кто-то из экспертов, посещающих RSDN или "Мастеров Дельфи" знает че не так.
Re[2]: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Аноним  
Дата: 12.04.02 02:46
Оценка:
Здравствуйте Yurik, Вы писали:

Y>Здравствуйте Иван Ходов, Вы писали:


ИХ>>procedure TForm1.Button2Click(Sender: TObject);

ИХ>>var
ИХ>>i,j: longint;
ИХ>>begin
ИХ>>for i := 0 to length(t)-1 do
ИХ>> Begin
ИХ>> for j := 1 to 4096 do
ИХ>> setlength(t[i]^[j],0);
ИХ>> dispose(t[i]);
ИХ>> End;
Y>SetLength(t, 0);
ИХ>>t:=nil;
ИХ>>end;
Нет. Не поможет. Это я даже не пробуя знаю.
X := nil;
и
SetLength(X, 0);
Это одна и та же операция и дублировать ее нет смысла.
Как я уже писал, если в первой процедуре не использовать S,
а присваивать значения сразу строкам в массиве, то утечки нету.

Y>Может, поможет. Ты, кстати, как утечки определяешь?

У меня есть MemProof, MemCheck, но эту утечку видно, даже в "Ctrl-Shift-Esc" :)
Re[2]: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Аноним  
Дата: 12.04.02 02:50
Оценка:
Здравствуйте AIR, Вы писали:

AIR>Может я и не прав, но мне кажется следующее. Если все есть так, как ты написал в самом конце пояснения, то у тебя при выходе из первой процедуры не вычищается кусок, ассоциированный с p ( new(p) ). Раз уж ты выделил его сам, то сам и зашибай!!!! ( delete(p) ). А то при выходе указатель созданный на стеке пришибается, а распределенная память не вычищается, ведь автосборщика "мусора" нет!


Вероятно, Вы ошибаетесь. Если я буду использовать delete(p) в первой процедуре, то не смогу обратиться к этой памяти во второй процедуре. А память вычищается строкой
dispose(t[i]);
Re: Люди!!! Ткните мне, пожалуйста, пальцем в утечку!!
От: Аноним  
Дата: 12.04.02 14:28
Оценка:
Здравствуйте Иван Ходов, Вы писали:

ИХ>Я сделал упрощенный пример, который моделирует мою проблему. Вот две процедуры, которые реагируют на кнопки на форме.

ИХ>Как Вы легко поймете, первая, с каждым новым кликом, создает массив строк, которым присваивает различную длину.
ИХ>Вторая должна почистить память.
ИХ>Но в результате, если нажимать по такой схеме:
ИХ>12
ИХ>112
ИХ>1112
ИХ>11112
ИХ>и т.д., т.е. 1-ю кнопку нажимать все больше раз, то происходит все большая утечка памяти примерно по 4-8 Kb.

ИХ>Расскажите, пожалуйста в чем дело?!?!?!?


ИХ>type

ИХ> ptry1=^ttry1;
ИХ> ttry1=array[1..4096] of string;

ИХ>TForm1 = class(TForm)

ИХ> Button1: TButton;
ИХ> Button2: TButton;
ИХ> procedure Button1Click(Sender: TObject);
ИХ> procedure Button2Click(Sender: TObject);
ИХ> private
ИХ> { Private declarations }
ИХ> public
ИХ> t : array of ptry1;
ИХ> { Public declarations }
ИХ> end;


ИХ>procedure TForm1.Button1Click(Sender: TObject);

ИХ>var
ИХ>p : ptry1;
ИХ>i : longint;
ИХ>s : String;

ИХ>begin

ИХ>new(p);
ИХ>for i:=1 to 4096 do
ИХ> Begin
ИХ> setlength(s,i);
ИХ> p^[i] := s;
ИХ> setlength(s,0);
ИХ> End;
ИХ>i := length(t);
ИХ>setlength(t, i+1);
ИХ>t[i] := p;
ИХ>end;

ИХ>procedure TForm1.Button2Click(Sender: TObject);

ИХ>var
ИХ>i,j: longint;
ИХ>begin
ИХ>for i := 0 to length(t)-1 do
ИХ> Begin
ИХ> for j := 1 to 4096 do
ИХ> setlength(t[i]^[j],0);
ИХ> dispose(t[i]);
ИХ> End;
ИХ>t:=nil;
ИХ>end;

ИХ>там реальный код сложнее. Этот — просто макет, который производит ту же утечку, что и реальная прога.


ИХ>Я знаю, что если в первой процедуре на использовать s, а сразу устанавливать длину для элементов массива, то утечки нету. Так в чем проблема? кто знает?


1.
Что такое t?
2. setlength(t[i]^[j],0); ??????????!!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.