Saturday, July 13, 2013

Memory management in Objective - C


Bonjour les amis,

 
This post explains the memory management in Objective-C .
Amigos with C++ background can also refer to this post as it will help them to get a basic idea of how the memory is allocated  and should be handled by you. If you have worked or working on any in house frameworks, this post will help you to get some overview of how memory handler module works in your  your framework.

Before going any further I would first like to explain the "
Brique de fooundation" of memory management in C++, Reference counting. Consider two programmers working on two different classes but using same reference of any object xyz. Now who will delete the memory allocated to this object? If programmer1 delete the object and programmer 2 is still using it he will get a crash. Now how the programmers will know when to delete the object and who will delete it ? Now consider the same situation in a large project where many programmers are working on different classes and they all uses many such object's reference in different classes!!!! problemas? Of-course it's a big problem!!! To solve this issue reference counting was engineered.


What is reference counting ?


Definition from wiki : 
In computer science, reference counting is a technique of storing the number of references, pointers, or handles to a resource such as an object, block of memory, disk space or other resource.

In layman language a reference count is an internal count managed by an object, indicating the count that someone has its ownership.

What is ownership:  An owner of an object is the code snippet which states that "it needs that particular object and no one can delete it".

Methods/Messages related to memory management in Objective- C

alloc (also called "new") : This will create a new object and claims an  ownership of it.

      alloc will explicitly creates an instance of an object. The piece of code creating object using alloc is the only whole soul owner of that object and should delete that object when it has done with it. This will increase the retain count of that object by one. 


retain : This will claim an ownership of an existing object      retain will increase the retain count (reference count) by 1 and makes the calling piece of code a new owner of that object. So some one using retain can say I am also the owner so no one should delete the object till I am done with it . Here also the object should be deleted once its usage is over.


copy : Creates a copy of an object and claims an ownership of it 

    copy will create a copy of the existing object and makes the calling piece of code the owner of that copy of object. So this copy will manage the separate track of retain count. And this copy of object should be deleted when its usage is done.

release : This will delete the object and take away the ownership.

    release will will delete the object decreasing its reference count by 1. But remember "only owner should use it".
 
autorelease :
This will delete the object automatically and don't give the ownership.
    with autorelease  you don't lock the object but you be the temporary owner of the object such that it is deleted automatically when after sometime its usage is over. All the objects are kept in a memory pool called autorelease pool ( an instance of NSAutorelease class) and are deleted at once like  a garbage collector when the pool cleaned. The reference count is made 0 when the objects are deleted.
 
   ARC ("automatic reference counting") is the  the garbage collector mechanism in Objective - C  . All new projects generally uses ARC to prevent the overhead of manual memory management.



Thursday, July 4, 2013

Shallow and Deep Copy in C++

!Hola,

Hope!  my last post was useful for you guys. Guess now you are  aware of dynamic memory allocation for an Array !!!  This post explains the Shallow and Deep copy. Another confusing topic of object oriented programming.

Before proceeding please make sure that you know what is constructor. ( Great!!!!,  that is the minimum qualification required to understand this post)

Now what is a copy constructor ?
A copy constructor is used to copy an object. Suppose we have a class named Dreams. Then the syntax for declaring the copy constructor will be:

syntax:

public Dreams (Dreams & otherDreams);



Make sense!!! 
So what are we doing above ? We are passing the address of the Dream's object to the constructor.
Note : In C++ even if you don't create any constructor, the compiler by default adds a default constructor (interview question)
The default copy constructor provided by the C++ compiler always does the shallow copy. But what actually is a shallow copy? For this let us look into a code snippet below:

class Dreams

{
    public:
    int dreamSize;
     String * dreamCategory;

    
     // empty constructor
     Dreams( )

     {
             dreamSize = 10;
             dreamCategory = new String[dreamSize];
      }

     // copy constructor
     Dreams(Dreams & otherDreams)

     {
         dreamSize = otherDreams.dreamSize;
         dreamCategory = others. dreamCategory;     // note this usage of " = "
      }
  
      ~ Dreams()
      {
             delete[] (this->dreamCategory);
       }
};

class Test

{
      int main( )
     {
          Dreams dream1; // calls  empty constructor
          dreams1.dreamCategory[ 0 ] = 20 ;

         {
               Dreams dream2(dream1);  // calls copy constructor
               cout <<" value of dream1.dreamCategory[0] : %d", dreams1.dreamCategory[ 0 ];

         }    
       
         //segmentation fault error below

         cout <<" value of dream1.dreamCategory[0] : %d", dreams1.dreamCategory[ 0 ];
         return 0;

   }
};


so what is happening here ?
in main() we first created a object  dream1 then we created object dream2 of class Dreams to which we passed dream1.This will call the copy constructor which in turn assigns the member's value of dream1 to dream2.

Did you noticed something awkward happening above? Will the code run properly ?
Answer is no , it will give segmentation fault error!!!!!

Consider the scope of dream2 ( dream2 is inside curly-braces ) . Once the scope of dream2 ends the destructor will be called and the memory allocated for the dream2.dreamCategory will be deleted so will be deleted for dream1.dreamCategory

Why?

Because in copy constructor 
dreamCategory = others. dreamCategory;  will allocate same memory allocation for  dream1.dreamCategory and dream2.dreamCategory.  THIS TYPE OF COPYING IS CALLED SHALLOW COPY





To prevent this we need to create our own version of copy constructor and allocate memory for dream2.category separately like this.

class Dreams

{
    public:
    int dreamSize;
     String * dreamCategory;

    
     // empty constructor
     Dreams( )

     {
             dreamSize = 10;
             dreamCategory = new String[dreamSize];
      }

     // copy constructor
     Dreams(Dreams & otherDreams)

     {
         dreamSize = otherDreams.dreamSize;
         dreamCategory = new String[dreamSize]; // explicit memory allocation
         for(int i = 0, i < otherDreams.dreamSize; i++)

         {
                 dreamCategory[i] =  otherDreams.dreamSize[i];
         }

        // you can also use std::copy instead of for loop      
      }
  
      ~ Dreams()
      {
             delete[] (this->dreamCategory);
       }
};

class Test

{
      int main( )
     {
          Dreams dream1; // calls  empty constructor
          dreams1.dreamCategory[ 0 ] = 20 ;

         {
               Dreams dream2(dream1);  // calls copy constructor
               cout <<" value of dream1.dreamCategory[0] : %d", dreams1.dreamCategory[ 0 ];

         }    
       
         //no segmentation fault error below

         cout <<" value of dream1.dreamCategory[0] : %d", dreams1.dreamCategory[ 0 ];
         return 0;

   }
};

Here as you see we have explicitly allocated memory for dream2.THIS TYPE OF COPYING IS CALLED DEEP COPY.  So the memory map will look like this:




Hope this post was useful. Please give  your valuable comments or if you have any queries feel free to post.

Wednesday, July 3, 2013

Dynamic Memory Allocation For Arrays in C++

!Hola,

This post describes the way to make dynamic allocation for arrays in C++. Sounds interesting ?
For beginners this might be little bit confusing. So, specially for them let me take an example from JAVA. Can you recall how a 1-D array is created in java?

int x[ ] = new int [3];

make sense ? OK !!! so what is the role of "new" here?

new operator allocates memory for three integer elements of array x. Now if you go to Arrays topic of any JAVA book you will find the way to make dynamic array. Now for instance check the 2D array below.

int x[ ][ ] = new int[4][ ];
x[0] = new int[1];
x[1] = new int[2];
x[2] = new int[3];
x[3] = new int[4];

will allocate memory for this array like this:



Make sense !!!!!

I guess you might have got an idea what does dynamic array means. Cool !!!
Now the question is how you will do this in C++ ?
The solution for this is pointers.

We will make use of pointers to dynamically declare and initialize arrays just like we did above with JAVA. The code snippet below will explain everything.



syntax to dynamically create 2-D array:

Object **array;
array = new Object* [rowsize];

for(int i = 0; i < rowsize; i++)
array[i] = new Object[columnsize];

 

example of 1-D array:

int* x = new int[2];
x[0] = 1;
x[1] = 2;

example of 2-D array: ( check this, its similar to what we did above with JAVA )

    int ** a = new int*[2];
    a[0] = new int[2];
    a[0][0] = 1;
    a[0][1] = 2;
    a[1] = new int[3];
    a[1][0] = 3;
    a[1][1] = 4;
    a[1][2] = 5;
   

example of 3-D array:

    int *** b = new int**[2];
    b[0] = new int*[2];
    b[0][0] = new int[2];
    b[0][1] = new int[2];
    b[0][0][0] = 1;
    b[0][0][1] = 2;
    b[0][1][0] = 3;
    b[0][1][1] = 4;
   
    b[1] = new int*[2];
    b[1][0] = new int[2];
    b[1][1] = new int[2];

    b[1][0][0] = 5;
    b[1][0][1] = 6;
    b[1][1][0] = 7;
    b[1][1][1] = 8;

Hope it was useful !!

Tuesday, July 2, 2013

When POINTERS marry CONSTANTS !!!! :O

POINTERS weds CONSTANTS

¡Hola,


            This post describes one of the confusing topic in C/C++ . Relationship between Pointers and Constants.

Before going to details first of all I would like to brief some basics:


1) Reference & Pointer


The address that locates a variable within memory is called "reference" to that variable. Remember "&" you see all around your C/C++ project :D . Yes!!! its the same.

So, what is pointer :O !!!!

Pointer is a variable that stores the reference to a variable. In other word a pointer points to a variable whose reference it stores.

int i = 10;
int *ptr;  //  pointer
ptr = & i;

/* ---------
here ptr is pointer
and &i is the reference of i (in layman language address of i)What the hell is "*""*" is called the
Dereference operator (*)

* can give you the value from address.
so if
int j = *ptr;
then j == 10 is true;
*/

2) Constant


As the name says constants are entities that don't change its value through out the code.

syntax:

const int i = 10;
or int const i = 10;
both are same ;)


 

POINTERS (hubby)" engaged to" CONSTANTS (wife)


                 There are three types of relationship between constants and pointers.

1) Pointer to Constant


Here the pointer cannot change the value of variable whose address it stores. But can change the address it is storing. (Husbands are not faithful !!!! :O  they  can have someone else in there heart :P  and they can't change wife's nature :D)

eg:

int i = 10;

int j = 20;
const int *ptr = &i;  //
int const *ptr = &i;  !!! is also valid  :O :P
*ptr = 100; // invalid :
assignment of read-only variable ‘ptr’
ptr = &j ; // valid

2) Constant pointer to variable


Here the pointer can change the value of variable whose address it stores. But cannot change the address it is storing. (Husbands are faithful and are smart enough to change wife's nature  :O)
eg:

int i = 10;

int j = 20;
int *const ptr = &i; 


*ptr = 100; // valid 

ptr = &j ;  // invalid : assignment of read-only variable ‘ptr’


3) Constant pointer to constant


Here the pointer neither change the value of variable whose address it stores. Nor it can change the address it is storing. (Husbands are faithful and  helpless :D :P)


eg:

int i = 10;

int j = 20;
const int *const ptr = &i; 


*ptr = 100; //
invalid : assignment of read-only variable ‘ptr’
ptr = &j ;  // invalid : assignment of read-only variable ‘ptr’


Up Qualification & Down Qualification


int i = 10;
const int j = 20;
int * ptr1;
const int *ptr2;

ptr1 = &i; // valid
ptr1= &j; // invalid: called down qualification in C/C++

ptr2 = &j; // valid
ptr2= &i;  // valid : called up qualification in C/C++



Summary



   
int i = 10;
    int j = 20;
    int* ptr0;
    const int* ptr1 = &i;    // int const * ptr1;
    int *const ptr2 = &i;
    const int *const ptr3= &i;
       
    *ptr1 = j; // invalid
    ptr1 = &j ; //valid
   
    *ptr2 = j; //valid
    ptr2 = &j; // invalid

    *ptr3 = j; //invalid
    ptr3 = &j; // invalid
   
    ptr1= &pp; // valid : up qualification
    ptr0 = &pp; // invalid : down qualification