Wednesday 18 April 2012

C language

Object Lifetime

In C#, destroying an object is a two-step process that corresponds to and reverses the two-step object creation process.



Creating Objects

In the last posts, we learned that creating a C# object for a reference type is a two-step process, as follows:
  1. Use the new keyword to acquire and allocate memory. 
  2. Call a constructor to turn the raw memory acquired by new into an object.

Destroying Objects

Destroying a C# object is also a two-step process:
  1. De-initialize the object.

    This converts the object back into raw memory. In C# this is done by the destructor. This is the reverse of the initialization performed by the constructor. We can control what happens in this step by writing our own destructor or finalize method.
  2. The raw memory is de-allocated; that is, it is given back to the memory heap.

    This is the reverse of the allocation performed by new. We cannot change the behavior of this step in any way.

OBJECTS AND SCOPE

Unlike values such as int and struct values, which are allocated on the stack and are destroyed at the end of their scope, objects are allocated on the managed heap and are not destroyed at the end of their scope.

Values

The lifetime of a local value is tied to the scope in which it is declared. Local values are variables that are allocated on the stack and not on the managed heap. This means that if we declare a variable whose type is one of the primitives (such as int), enum, or struct, we cannot use it outside the scope in which we declare it. For example, in the following code fragment, three values are declared inside a for statement, and so go out of scope at the end of the for statement:

struct Point { public int x, y; }
enum Season { Spring, Summer, Fall, Winter }
class Example
{
  void Method(int limit)
  {
    for (int i = 0; i < limit; i++) {
      int x = 42;
      Point p = new Point( );
      Season s = Season.Winter;
      ...
    }


    x = 42; // Compile-time error
    p = new Point( ); // Compile-time error
    s = Season.Winter; // Compile-time error
  }
}
 

Note

In the previous example, it appears as though a new Point is created. However, because Point is astruct, new does not allocate memory from the managed heap. The “new” Point is created on the stack.

This means that local values have the following characteristics:
  • Deterministic creation and destruction

    A local variable is created when we declare it, and is destroyed at the end of the scope in which it is declared. The start point and the end point of the value’s life are deterministic; that is, they occur at known, fixed times.
  • Usually very short lifetimes

    We declare a value somewhere in a method, and the value cannot exist beyond the method call. When we return a value from a method, we return a copy of the value.

Objects

The lifetime of an object is not tied to the scope in which it is created. Objects are initialized in heap memory allocated through the new operator. For example, in the following code, the reference variable eg is declared inside a for statement. This means that eg goes out of scope at the end of the for statement and is a local variable. However, eg is initialized with a new Example( ) object, and this object does not go out of scope with eg. Remember, a reference variable and the object it references are different things.

class Example
{
  void Method(int limit)
  {
    for (int i = 0; i < limit; i++) {
      Example eg = new Example( );
      ...
    }


  // eg is out of scope
  // Does eg still exist?
  // Does the object still exist?
  }
}
 

This means that objects typically have the following characteristics:
  • Non-deterministic destruction

    An object is created when we create it, but, unlike a value, it is it not destroyed at the end of the scope in which it is created. The creation of an object is deterministic, but the destruction of an object is not. We cannot control exactly when an object will be destroyed.
  • Longer lifetimes

    Because the life of an object is not tied to the method that creates it, an object can exist well beyond a single method call.

0 comments: