Delphi内存泄漏字符串?

时间:2014-07-15 07:26:09

标签: string delphi memory-leaks copy

我有一个程序接受SQL查询作为命令行参数,查询PostgreSQL数据库并生成一个以多种方式之一格式化的文件(通常用于生成CSV文件)。

然而,这个程序有严重的内存泄漏 - 一个特定的查询产生12MB文件,该程序使用8GB的RAM加上几GB的交换空间,然后操作系统将其杀死。我想找到这个内存泄漏的原因。我不太了解德尔福(从程序的质量来看,原作者也没有),但我的任务是找到快速解决方案。

以下doData函数部分输出结果集的单行。我猜测问题出在" copy"命令(在堆上创建一个永远不会被释放的字符串),但我确信比我更有经验的人能够确认这个答案或指出我正确的方向。

procedure doData;
var
    s, fldVal : string;
    i, fldLen : integer;
begin
    s := '';

    for i := 0 to ds.Fields.Count-1 do
    begin
        if (ds.Fields[i].DataType = ftDate) or
           (ds.Fields[i].DataType = ftDateTime) then
        begin
            if  psql.outDate = 'i' then
                fldLen := 8
            else
                fldLen := 10;

            if  ds.Fields[i].IsNull then
                fldVal := ''
            else
                fldVal := formatDate(ds.Fields[i].AsDateTime);
        end
        else
        begin
            fldLen := ds.Fields[i].DisplayWidth;
            fldVal := ds.Fields[i].AsString;
        end;

        if (psql.outType = 'd') or (psql.outType = 's') then
            s := s + trim(fldVal)

        else if psql.outType = 'f' then
        begin
            s := s + fldVal;

            if  fldLen - length(fldVal) > 0 then
                s := s + copy(spaces, 1, fldLen - length(fldVal));
                // Is this a memory leak above?
        end;

        if psql.outType = 's' then
        begin
            if i < ds.Fields.Count-1  then
           s := s + psql.outDelimChar;
        end
        else
            s := s + psql.outDelimChar;
    end;

    writeln(psql.outPrefixData + s);
end;

1 个答案:

答案 0 :(得分:4)

此代码中没有泄漏。 Delphi string类型由编译器管理,不需要程序员显式释放内存。

如果您希望找到泄漏,则应包括FastMM的完整调试版本。这将生成代码中任何泄漏的诊断报告,包括有助于识别泄漏内存最初分配位置的堆栈跟踪。