Tuesday, January 31, 2012

Compiler's implementation of New and Delete operators

Digging deeper into the implementation of New and Delete operators,  raises couple of question as listed below.
  • Under what circumstances a bad_alloc exception is thrown.
  • What if there is an exception thrown inside a constructor.
  • Who releases the heap memory allocated for the object, when constructor fails.
  • Is it possible to reuse a chunk of memory on the heap to reconstruct the object.
  • How to distinguish whether the exception is due to heap allocation error or due to a failing constructor.



Rather trying to answer these questions individually, it's better to explore compiler implementation of  " new " and " delete " operators which eventually answers the above questions.











 Consider CellPhone,a class declaration below

     class CellPhone
     {
         long IMEI ;
         char* DeviceName ;
      public:
         CellPhone(int ID, char* Name)
         {
             IMEI = ID ;
             strcpy(DeviceName,(char*)malloc(sizeof(strlen(Name)+1)));
         }
         void* operator new ( size_t size );
         void operator delete (void* buffer);
     };

The below instruction creates an instance of this class on the heap through " new " operator.

  CellPhone* PhoneObject = new CellPhone(900,"NOKIALUMIA") ;

New Operator
The "new" operator instantiates an object on the heap in two steps.

1) Allocate the required amount of  memory for the object, on heap
2) Call constructor of the class to initialize the object.

Instantiating the object on heap
To allocate memory on the heap "new" operator uses a function " operator new " as shown in the class declaration. This function allocates memory specified by " size_t " parameter on heap for the object and returns a " void* " pointer. And if the memory allocation fails, run-time will throw a " bad_alloc " exception.

      void* CellPhone::operator new(size_t size) throw (const char*)
      {
        void* buffer = malloc(size);    
        if(buffer = NULL) throw "Not enough memory to allocate for the object";
        return buffer ;
      }

The above function can be overloaded by the developer to provide custom implementations and excemption details.

Initializing the object by calling constructor 
Run-time achieves this functionality through " Placement new " operator which basically receives  " void* " pointer returned by " operator new " function, allocated on the heap and calls constructor of the  class to initialize the object as shown below.

Calling operator new function.
    void* buffer = operator new(sizeof(CellPhone)); // ----------->1

Typecast void* pointer to class specific pointer.
  CellPhone* PhoneObject = dynamic_cast<CellPhon*>(buffer);//Simple  static cast also would do.

Constructing the object at the allocated space using " placement new " operator.
    try
    {
       new(PhoneObject)CellPhone(900,"NOKIA LUMIA"); //------------> 2
    }
    catch(exception& e)
    {
        cout << e.what();
        operator delete( PhoneObject );
        throw "Exception inside constructor";
    }
    
    void CellPhon::operator delete (void* buffer)
    {
       free(buffer);
       buffer = NULL ;    
    }

The above programming structure clearly explains, how the exceptions from constructor is handled. The " placement new " operator shown in instruction #2 receives pointer to the buffer allocated as shown in instruction #1 and tries to construct the object at that location.
During this process if there is any exception thrown inside the constructor it is caught and the allocated memory is released back to heap using " operator delete ( ) " function, which is a compliment of " operator new ( ) " function.
With the above implementation user would be clearly able to distinguish whether the " new " operator failed due to "heap allocation error " or due to " exception thrown " inside the constructor.

I hope this article was helpful in demystify obscure implementation details of  "New" and "Delete" operators. Suggestions and comments if any is appreciated.

4 comments:

  1. I have to express my appreciation to the writer for rescuing me from this particular incident. Right after looking out through the world-wide-web and meeting strategies which were not beneficial, I believed my life was over. Existing without the presence of strategies to the problems you've resolved by way of this guideline is a crucial case, as well as the kind that would have in a negative way affected my career if I had not come across your blog post. Your good understanding and kindness in playing with a lot of things was crucial. I don't know what I would've done if I had not discovered such a point like this. I can at this time relish my future. Thanks a lot so much for your specialized and effective help. I won't think twice to suggest your web sites to any person who wants and needs guidelines on this topic.
    Perry Ellis Men's Gingham Swim Trunk

    ReplyDelete
  2. obviously like your website but you have to take a look at the spelling on several of your posts. Several of them are rife with spelling issues and I to find it very bothersome to tell the reality however I'll certainly come again again.
    Bogs Women's Classic High Tuscany Rain Boot

    ReplyDelete
  3. Hi Joshua W.Ross,
    I am very delighted to find that this article could help you at your work.
    And I also appreciate your effort to provide feedback on the same.
    Thank you.

    ReplyDelete
  4. Hi Jonathan A.Coleman,
    Thanks for being very candid and pointing-out areas of improvement with my articles.
    I'll take special care while I write articles in future and ensure to reduce these errors as much as I can.

    Thank you.

    ReplyDelete

ShareThis