При работе с JSON, а я для этого сделал небольшую "обертку" (JSONные войны в Lazarus), обнаружил серьёзные утечки памяти. Обнаружил несколько ошибок и вот настало время исправлений.
У меня был такой кусок:
function TJSON.Parse(aString: string): Boolean;
var
D : TJSONData;
P : TJSONParser;
i:Integer;
begin
result:=false;
P:=TJSONParser.Create(aString);
D:=P.Parse;
Clear;
try
for i:=0 to D.Count-1 do begin
Add(TJSONObject(D).Names[i],TJSONObject(D).Items[i]);
end;
except
FreeAndNil(P);
exit;
end;
FreeAndNil(P);
result:=true;
end;
Ошибка возникает тут: D:=P.Parse; . Дело в том что создаётся новый объект - TJSONData, который впоследствии безжалостно разделяется методом Add и TJSONObject(D).Items[i]. Для подобных случаев у TJSONObject есть метод Extract - он выделяет ветвь удаляя у себя ссылку на нее.
Метод приобрёл следующий вид:
function TJSON.Parse(aString: string): Boolean;
var
D : TJSONData;
P : TJSONParser;
jodata: TJSONData;
joname: String;
begin
result:=false;
P:=TJSONParser.Create(aString);
D:=P.Parse;
FreeAndNil(P);
Clear;
try
while D.Count>0 do begin
joname:=TJSONObject(D).Names[0];
jodata:=TJSONObject(D).Extract(0);
Add(joname,jodata);
end;
except
FreeAndNil(D);
exit;
end;
FreeAndNil(D);
result:=true;
end;
Вроде бы утечки памяти пропали.
Комментариев нет:
Отправить комментарий