Skip to main content

Dynamic Memory allocation in C++

Similar to C, C++ supports allocating memory at run time in the heap.

 In C we use malloc(), calloc() and realloc() for this operation. And the memory thus allocated, is released using free().

 In C++ dynamic memory allocation uses two operators instead of functions,
new and delete. Both these operators work on all basic data types as well as user defined classes and structures

new operator

new operator allocates memory to a variable and returns a pointer to it. new does not need number of bytes to be allocated, instead it needs data type of pointee.


 int *ptr = new int;

Here memory is allocated to an integer and its address is stored in ptr.  Value pointed by this pointer is not initialized.


To initialize the pointee we can use
the modified form

int *ptr = new int(10);

We have allocated memory for ptr and stored 10 in the location pointed by ptr.

If new operator fails, it throws a bad_alloc exception.

new[] operator

The second version of new  is new[]. This is used to allocate memory for multiple values. And the pointer once allocated can be accessed  using array syntax.

For example, to allocate memory for a block of 10 integers, you can use

int *ptr2 = new int[10];/*allocate memory to 10 integers. */

Let us look at some examples with new and new[]
int main()
{
 int *ptr;
 ptr = new int;
 cout<<"Enter a number";
 cin>>*ptr;
 cout<<"You just entered"<<*ptr;
 float * arr = new float[5];
 for(int i=0;i<5;i++)
 {
 cin>>arr[i];
 }
 delete ptr;
 delete [] arr;
}
 

The program above allocates  5 floats using new float[5]. You can observe that 5 floats allocated for arr are accessed using subscript operator([]).

delete operator

delete operator is used for releasing memory allocated using new.
delete ptr;
delete []ptr2;

delete with square brackets (delete []) is used to release memory allocated to multiple values. It is used to release memory allocated using new []
Any memory allocated using new operator should always be released using delete to avoid memory leaks.


Memory Leaks

Whenever you allocate memory using new operator, you should always release the memory using delete, after you have completed its usage. Because unlike other variables, dynamically created variables are not destroyed automatically when they go out of scope.

If memory is not released, at some point of time, the program will run out of memory. This is called memory leakage.

new and delete for objects


Memory can be allocated to classes and structures  too  using new and delete operators. new will allocate memory to an object, create the object and also call the constructor for the object.

delete will call the destructor and then destroy the object and release the memory.

Difference between malloc and new:

You can still use malloc() in C++. But malloc needs the user to specify the number of bytes to be allocated and malloc does not call constructor for objects.


Memory allocated using malloc can be released using free. But free does not call destructor for objects.


int *ptr = malloc(sizeof(int));
*ptr = 10;
free(ptr);

Memory allocated using new should be released using delete. And memory allocated using malloc should be released using free.

this pointer

You see a special pointer this in many methods of the class. What is it?

this is a pointer to the object which called this method. It is a pointer to the current object. Whenever we use a non-static member of a class in a method, there is an implicit this-> present.

class A
{
   int m;
public:
   void print();
   int getm();
};
void A::print()
{
    cout<<this->m;
}
int A::getm()
{
    return this->m;
}

Remember the discussion that a static method can not use this pointer.

Comments

Popular posts from this blog

Constant members of a Class

A constant  is a value which can not be modified. As in C, we can have literal constants using #define and we can have enums and we can define a variable to be const .  Let us look at const variables here. By declaring a variable as const , we ensure that it is not modified accidentally. Any modification to a constant will give a compilation error. A const should always be initialized while defining. In the program below,  assignment to pi gives a compiler error because pi is defined as const and code is trying to modify this. int main () { const float pi = 22.0/7 ; int radius = 12 ; radius ++ ; /*ok*/ pi = 3.14 ; /*error*/ }   Constant parameters to functions Even function parameters can be const ant. We have earlier discussed that making a reference parameter as constant will avoid the function from accidentally modifying the argument. void printnum ( int & n) { cout << n ++ ; } void printnum2 ( const int & n) { cout <&l

Polymorphism

You hear the term Polymorphism too frequently with object oriented languages. Along with Inheritance and Encapsulation, polymorphism is one of the corner stones of object oriented design. What is Polymorphism, exactly? Polymorphism is a mechanism by which you provide single interface for multiple methods. (poly - many, morph - form). In C++, polymorphism can be compile time or run-time. Compile time polymorphism is provided with the help of overloaded operators/functions and templates. Run time polymorphism is provided with the help of virtual functions and late binding. Late Binding: Connecting a function call to function body is called binding. Most functions use early binding where this binding happens before the program is run - during compile time. This is also called static binding. Late binding (also called dynamic binding)  is when a function call is connected to function body at run time. This is done after looking at the type of the object. Late binding is ach

Operator Overloading

What is operator overloading ? Operator overloading is the process of customizing C++ operators for operands of user defined types.   When you have two objects of a class- num1 and num2 , you can write a function to add them such as  ans = add(num1,num2); That does not look neither simple nor intuitive. You would prefer to write      ans = num1+num2; as you would write expressions for basic data types like integers, floats etc.    This can be done using Operator overloading. Operator overloading lets you write such statements. That is, it lets you call your functions on objects using  +, - ,* etc.    + operator will call addition function on the object (when you write op. overloading function for +). * will call multiply on objects etc. Names of overloaded operator functions start with keyword operator followed by  symbol of the operator. e.g. +, - etc. Unary operator functions take 0 parameters for members. The operand for these function is the object cal