C#


CSHARP.ALLOC.LEAK.NOTCLOSED : Closeable Not Closed (C#)

Summary

A resource should be closed by the end of the method where it is created.

The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources (such as database, streams, open files, etc.). For these reasons, they should be disposed, or otherwise the system might run into an out of resource exception. The dispose operation should always be performed, in every execution path. For this reason, the using or finally constructs should be used.

This checker verifies that resources are always released after being open, for every execution path. This checker recognizes and accepts as correct code where a resource is stored into a field or returned from a method and is then closed at the end, at least for some frequent scenarios.

Properties

Class Name Closeable Not Closed (C#)
Significance reliability
Mnemonic CSHARP.ALLOC.LEAK.NOTCLOSED
Categories
CWE CWE:772 Missing Release of Resource after Effective Lifetime
Availability Available for C# only.
Enabling Checks for this warning class are enabled by default. To disable them, add the following WARNING_FILTER rule to the project configuration file.
WARNING_FILTER += discard class="Closeable Not Closed (C#)"

Example


using System.IO;

namespace Example
{
    class TestCloseOfResources
    {
        void Foo(string path1, string path2)
        {

            FileStream file1 = File.Open(path1, FileMode.Open);    // "Closeable Not Closed (C#)" warning issued here
            int n = file1.Read(b, 1, 1);
            
            var r = File.Open(path2, FileMode.Open).Read(b, 2, 2); // "Closeable Not Closed (C#)" warning issued here

        }
    }
}

An example of possible fix:


using System.IO;

namespace Example
{
    class TestCloseOfResources
    {
        void Foo(string path1, string path2)
        {
            byte[] b = new byte[32];

            FileStream file1 = null;

            try
            {
                file1 = File.Open(path1, FileMode.Open);
                int n = file1.Read(b, 1, 1);
            }
            // catch exceptions
            // ...
            finally
            {
                if(file1 != null)
                    file1.Dispose();
            }

            using (FileStream file2 = File.Open(path2, FileMode.Open))
            {
                var r =  file2.Read(b, 2, 2);
            }

        }
    }
}

Resolution

Guarantee that all resources are released, typically by using a using or a finally construct. In general, avoid storing resources into fields or returning resources from methods or letting a method close a resource passed to it as a parameter.

Relevant Configuration File Parameters

The following configuration file parameters affect checks for this warning class.