The code below creates a memory leak. What is the correct method?
JSONArray := TJSONArray.Create;
try
JSONArray :=
TJSONObject.ParseJSONValue(
TEncoding.UTF8.GetBytes(
'[{"username":"admin"},{"username":"developer"}]'
), 0
) as TJSONArray;
finally
JSONArray.Free;
end;
CodePudding user response:
The problem is the call to TJSONArray.Create
. You are creating your own TJSONArray
object, then overwriting the JSONArray
pointer to point at a completely different TJSONArray
object, leaking the original object you Create
'd.
So, simply get rid of that Create
call, you don't need it. You need to Free
only the object that ParseJSONValue()
returns.
Also, you don't need to convert the JSON string to bytes. ParseJSONValue()
has an overload that accepts a string
as input.
Try this:
JSONArray := TJSONObject.ParseJSONValue(
'[{"username":"admin"},{"username":"developer"}]'
) as TJSONArray;
try
// ...
finally
JSONArray.Free;
end;
CodePudding user response:
Just as an alternative to the valid provided solution, but using mORMot. IMHO simpler, cleaner and avoiding memory leaks:
program Project1;
{$APPTYPE CONSOLE}
uses
Syncommons;
var Json : TDocVariantData;
begin
Json.InitJSon('[{"username":"admin"},{"username":"developer"}]');
// Testing
assert(Json.Kind = dvArray);
assert(Json.Count = 2);
assert(TDocVariantData(Json.Values[1]).U['username'] = 'developer');
end.
Please, find further details and alternatives in the amazing documentation.