Деструктор связанного списка Object Pascal оставляет один блок несвободным

При реализации деструктора для этого класса односвязного списка в Object Pascal, почему в конце всегда остается один незанятый блок памяти?

Я пробовал использовать итеративный деструктор вместо рекурсивного, но он дает тот же результат.

Файл LinkedListMWI.pas

    {$mode objfpc}{$H+}{$J-}
    
    unit LinkedListMWI;
    
    interface
    
    uses SysUtils; 
    
    type
      TNode = class
      private
        var
          FData: Integer;
          FNext: TNode;
      public
        constructor Create(Data: Integer);
        destructor Destroy(); override;
      end;
    
      TLinkedList = class
      private
        var
          FHead: TNode;
      
      public
        constructor Create(Items: Array of Integer);
        destructor Destroy(); override;
      end;
    
    implementation
    
    constructor TNode.Create(Data: Integer); 
    begin
      inherited Create();
      Self.FData := Data;
      Self.FNext := Nil;
    end;
    
    destructor TNode.Destroy();
    begin
      FreeAndNil(Self.FNext);
      inherited Destroy();
    end;
    
    constructor TLinkedList.Create(Items: Array of Integer);
    var
      Head, Last, ThisNode: TNode;
      ThisItem: Integer;
    begin
      inherited Create();
      Head := Nil;
      for ThisItem in Items do
      begin
        ThisNode := TNode.Create(ThisItem);
        if not Assigned(Head) then
        begin
          Head := ThisNode;
          Last := Head;
        end
        else
        begin
          Last.FNext := ThisNode;
          Last := ThisNode;
        end;
      end;
      Self.FHead := Head;
    end;
    
    { TODO Still one block unfreed }
    destructor TLinkedList.Destroy();
    begin
      FreeAndNil(Self.FHead);
      inherited Destroy;
    end;
    
    end.

Файл MWI.lpr

    {$mode objfpc}{$H+}{$J-}
    
    program mwi;
    
    uses SysUtils, LinkedListMWI;
    
    var 
      Nums: Array of Integer = (1, 2, 3, 4, 5, 6, 7);
      List: TLinkedList;
    begin
      List := TLinkedList.Create(Nums);
      FreeAndNil(List);
    end.

Скомпилируйте с помощью fpc -vwhine -glh MWI.lpr

Результат:

15 memory blocks allocated : 1524/1536
14 memory blocks freed     : 1496/1504
1 unfreed memory blocks : 28
True heap size : 360448
True free heap : 360192
Should be : 360224
Call trace for block $0000FFFF80105500 size 28
  $0000000000400210  main,  line 11 of MWI.lpr
  $0000000000400168
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В коде связанного списка нет утечки памяти — несвободный блок взят откуда-то еще.

Я не знаю, как FPC обрабатывает инициализированные глобальные переменные динамического массива - если бы мне пришлось догадываться, я бы сказал, что это так.

Попробуйте изменить код на этот и проверьте еще раз:

var
  List: TLinkedList;
begin
  List := TLinkedList.Create([1, 2, 3, 4, 5, 6, 7]);
  FreeAndNil(List);`
end.

Другие вопросы по теме