Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception throw from constructor and what happen to instance and memory allocation?

I have class like this. ( This is just example)

    public class NewTest
    {
        public int I { get; set; }
        public NewTest()
        {                
            I = 10;
            throw new ApplicationException("Not Possible");
        }
    }

Now if I use class like this

 NewTest t = new NewTest();

In above line as NewTest constructor throw exception variable t never assign any value as before constuctor get complete it throw exception but as per test and also per other question ( Why throwing exception in constructor results in a null reference?) object is created.

Now this object is created in Heap but it does not hold any root variable for reference so does it create problem for garbage collection ? or Is it memory leak of something ?


Following example help me to clear my confusion. Another Example

 namespace ConsoleApplication1
 {
 class Program
 {
    static void Main(string[] args)
    {
        NewMethod();
        System.GC.Collect();
        Console.WriteLine("Completed");
        Console.ReadLine();
    }

    private static void NewMethod()
    {
        Object obj = null;
        try
        {
            Console.WriteLine("Press any key to continue");
            Console.ReadLine();
            NewTest t = new NewTest(out obj);
        }
        catch
        {
            Console.WriteLine("Exception thrown");
        }

        try
        {
            Console.WriteLine("Press any key to continue");
            Console.ReadLine();
            NewTest1 t = new NewTest1();
        }
        catch
        {
            Console.WriteLine("Exception thrown");
        }

        Console.WriteLine("Press any key to continue");
        Console.ReadLine();

        System.GC.Collect();

        Console.WriteLine("Press any key to continue");
        Console.ReadLine();           

    }
}

public class NewTest1
{
    public int I { get; set; }
    public NewTest1()
    {
        I = 10;
        throw new ApplicationException("Not Possible");
    }
}

public class NewTest
{
    public int I { get; set; }
    public NewTest(out Object obj)
    {
        obj = this;
        I = 10;
        throw new ApplicationException("Not Possible");
    }
  }
 }
like image 281
dotnetstep Avatar asked Dec 15 '22 02:12

dotnetstep


2 Answers

The other answers are correct; I will add to them the fun fact that finalizable objects whose constructor throws are still finalized. That means that a finalizer can operate on an object whose constructor did not complete normally. A finalizer must not assume that an object is initialized at the point when it is finalized. This is yet another in a long list of reasons why it is hard to write a correct finalizer.

like image 197
Eric Lippert Avatar answered Dec 16 '22 15:12

Eric Lippert


Throwing exceptions in the constructor is not a problem to garbage collector, and it definitely does not result in memory leaks.

Although the memory allocated from the heap never makes it to your program, it is available to the internal implementation of the operator new, which takes care of ensuring that the newly created instance becomes eligible for garbage collection.

like image 29
Sergey Kalinichenko Avatar answered Dec 16 '22 15:12

Sergey Kalinichenko