Search code examples
delphigenericsenumerator

Is it necessary to manage the lifetimes of TEnumerators from generic containers?


If I call the GetEnumerator method of a Generics.Collections object, do I need to explicitly free the enumerator when I'm done with it?


Solution

  • Yes you do need to free the enumerator. Whoever calls GetEnumerator owns what it returns.

    When it is a for/in loop the compiler writes the code and ensures that the enumerator object is disposed of. When you call it, it is your job to dispose of the enumerator.

    This is in fact a very easy question to answer for yourself. Simply create a program that calls GetEnumerator and fails to Free it. Use the memory manager's facilities to check whether or not the object is leaked.

    uses
      System.Generics.Collections;
    
    begin
      ReportMemoryLeaksOnShutdown := True;
      with TList<Integer>.Create do
      begin
        GetEnumerator;
        Free;
      end;
    end.
    

    And this results in the following leak report:

    An unexpected memory leak has occurred. The unexpected small block leaks are:

    • 13 - 20 bytes: TList.TEnumerator x 1