我在一个 Delphi Windows应用程序中有一个简单的函数,它在绕圈追着我。
如果我按如下方式运行它,我会得到一个内存泄漏:
function TtrackingsingleDlog.getJsonValue (const isScanDataB:boolean; scanNumberI: integer; pairnameS,fullStringS: string):string;
var
jobject: TJSONObject;
jobject2: TJSONObject;
scansarray: TJSONArray;
valueStringS:string;
begin
valueStringS:='';
jobject := TJSONObject.ParseJSONValue(fullStringS) as TJSONObject;
if isScanDataB then
begin
jobject.TryGetValue('data', jobject2);
if scanNumberI>=0 then
begin
if jobject2.TryGetValue('scans', scansarray) then
begin
scansarray[scanNumberI].TryGetValue<string>(pairnameS,valueStringS);
jobject2.free;
end;
end
else
begin
jobject2.TryGetValue(pairnameS, valueStringS);
jobject2.free;
end;
end
else
begin
jobject.TryGetValue(pairnameS, valueStringS);
jobject.free;
end;
result:=valueStringS;
end;
如果我注解掉if scanNumberI>=0
部分,并释放jobject
,如下所示,泄漏就消失了:
function TtrackingsingleDlog.getJsonValue (const isScanDataB:boolean; scanNumberI: integer; pairnameS,fullStringS: string):string;
var
jobject: TJSONObject;
jobject2: TJSONObject;
scansarray: TJSONArray;
valueStringS:string;
begin
valueStringS:='';
jobject := TJSONObject.ParseJSONValue(fullStringS) as TJSONObject;
if isScanDataB then
begin
jobject.TryGetValue('data', jobject2);
{if scanNumberI>=0 then
begin
if jobject2.TryGetValue('scans', scansarray) then
begin
scansarray[scanNumberI].TryGetValue<string>(pairnameS,valueStringS);
jobject2.free;
end;
end
else
begin
jobject2.TryGetValue(pairnameS, valueStringS);
jobject2.free;
end; }
jobject.free;
end
else
begin
jobject.TryGetValue(pairnameS, valueStringS);
jobject.free;
end;
result:=valueStringS;
end;
但是,如果我把那部分放回去,jobject.free
就会抛出一个访问冲突。
我肯定我在做蠢事,但就是不知道我错过了什么。
1条答案
按热度按时间rmbxnbpk1#
在您所展示的代码中,您负责释放的 * 唯一 * 对象是由
ParseJSONValue()
返回的对象(您应该使用try..finally
来保护它!).不要试图释放任何从JSON中提取的内部对象,因为它们默认由顶层JSON对象拥有,因此当您释放顶层对象时,它们将自动为您释放。
如果你想获得内部对象的所有权,你必须手动将它们的
Owned
属性设置为False
。试试这个: