понедельник, 15 апреля 2013 г.

JSON: Работа над ошибками

При работе с 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;

Вроде бы утечки памяти пропали.

Комментариев нет:

Отправить комментарий