Skip to content

Memory leak if writeable const is assigned the result of concatenating 2 or more strings.

Consider the following program:

program test;
{$mode objfpc}
{$h+}

var
  HideTheMemoryLeak: Boolean;

procedure Foo;
const
  S: String = '';
begin
  S := 'X';
  if HideTheMemoryLeak then Exit;
  S := S + 'Y';  // This line causes a memory leak
end;

begin
  HideTheMemoryLeak := (ParamCount = 1) and (LowerCase(ParamStr(1)) = 'hidethememoryleak');
  Foo;
end.

Compile with heaptrace enabled and run.

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>fpc -gl -gh test.pas
Free Pascal Compiler version 3.3.1 [2022/10/11] for i386
Copyright (c) 1993-2022 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling test.pas
Linking test.exe
20 lines compiled, 0.2 sec, 52576 bytes code, 2084 bytes data

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
Heap dump by heaptrc unit of "C:\Users\Bart\LazarusProjecten\ConsoleProjecten\test.exe"
1 memory blocks allocated : 15/16
0 memory blocks freed     : 0/0
1 unfreed memory blocks : 15
True heap size : 196608 (272 used in System startup)
True free heap : 196208
Should be : 196224
Call trace for block $016C9620 size 15
  $0040163F  FOO,  line 14 of test.pas
  $004016EC  main,  line 19 of test.pas

No run with the hidethememoryleak commandline parameter:

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test hidethememoryleak
Heap dump by heaptrc unit of "C:\Users\Bart\LazarusProjecten\ConsoleProjecten\test.exe"
3 memory blocks allocated : 108/112
3 memory blocks freed     : 108/112
0 unfreed memory blocks : 0
True heap size : 262144 (368 used in System startup)
True free heap : 261776

There will be no memory leak if strings are shortstrings, or if S (in Foo) is declared as var.
However, in the original code where this was observed, using a writeable const was by design.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information