Home | | Object Oriented Programming and Data Structures | Dynamic memory allocation

Chapter: Object Oriented Programming and Data Structure : Data Abstraction & Overloading

Dynamic memory allocation

Dynamic memory is allocated using operator new. new is followed by a data type specifier and, if a sequence of more than one element is required, the number of these within brackets [].

Dynamic memory allocation

Operators new and new[]

 

Dynamic memory is allocated using operator new. new is followed by a data type specifier and, if a sequence of more than one element is required, the number of these within brackets []. It returns a pointer to the beginning of the new block of memory allocated. Its syntax is:

 

pointer = new type

pointer = new type [number_of_elements]

 

The first expression is used to allocate memory to contain one single element of type type. The second one is used to allocate a block (an array) of elements of type type,

 

where number_of_elements is an integer value representing the amount of these. For example:

1

2

int * foo;

foo = newint [5];

 

In this case, the system dynamically allocates space for five elements of type int and returns a pointer to the first element of the sequence, which is assigned to foo (a pointer).

 

Therefore, foo now points to a valid block of memory with space for five elements of type int.


Here, foo is a pointer, and thus, the first element pointed to by foo can be accessed either with the expressionfoo[0] or the expression *foo (both are equivalent). The second element can be accessed either with foo[1] or *(foo+1), and so on...

There is a substantial difference between declaring a normal array and allocating dynamic memory for a block of memory using new. The most important difference is that the size of a regular array needs to be a constant expression, and thus its size has to be determined at the moment of designing the program, before it is run, whereas the dynamic memory allocation performed by new allows to assign memory during runtime using any variable value as size. The dynamic memory requested by our program is allocated by the system from the memory heap. However, computer memory is a limited resource, and it can be exhausted. Therefore, there are no guarantees that all requests to allocate memory using operator new are going to be granted by the system.

 

C++ provides two standard mechanisms to check if the allocation was successful:

 

One is by handling exceptions. Using this method, an exception of type bad_alloc is thrown when the allocation fails. Exceptions are a powerful C++ feature explained later in these tutorials. But for now, you should know that if this exception is thrown and it is not handled by a specific handler, the program execution is terminated.

 

This exception method is the method used by default by new, and is the one used in a declaration like:

foo = newint [5]; // if allocation fails, an exception is thrown

 

The other method is known as nothrow, and what happens when it is used is that when a memory allocation fails, instead of throwing a bad_alloc exception or terminating the program, the pointer returned by new is a null pointer, and the program continues its execution normally.

 

This method can be specified by using a special object called nothrow, declared in header <new>, as argument fornew:

 

foo = new (nothrow) int [5];

 

In this case, if the allocation of this block of memory fails, the failure can be detected by checking if foo is a null pointer:

 

int * foo;

 

foo = new (nothrow) int [5];

if (foo == nullptr) {

// error assigning memory. Take measures.

}

 

This no throw method is likely to produce less efficient code than exceptions, since it implies explicitly checking the pointer value returned after each and every allocation. Therefore, the exception mechanism is generally preferred, at least for critical allocations. Still, most of the coming examples will use the nothrow mechanism due to its simplicity.

 

Operators delete and delete[]

 

In most cases, memory allocated dynamically is only needed during specific periods of time within a program; once it is no longer needed, it can be freed so that the memory becomes available again for other requests of dynamic memory. This is the purpose of operator delete, whose syntax is:

 

delete pointer;

delete[] pointer;

The first statement releases the memory of a single element allocated using new, and the second one releases the memory allocated for arrays of elements using new and a size in brackets ([]).

 

The value passed as argument to delete shall be either a pointer to a memory block previously allocated with new, or a null pointer (in the case of a null pointer, delete produces no effect).

 

// rememb-o-matic #include <iostream> #include <new> usingnamespacestd; int main ()

{

 

inti,n; int * p;

cout<<"How many numbers would you like to type? ";

cin>>i;

 

p= new (nothrow) int[i];

if (p == nullptr)

 

cout<<"Error: memory could not be allocated";

else

{

for (n=0; n<i; n++)

{

 

cout<<"Enter number: ";

cin>> p[n];

}

 

cout<<"You have entered: ";

for (n=0; n<i; n++)

 

cout<< p[n] <<", ";

delete[] p;

}

return 0;

}

 

How many numbers would you like to type? 5

Enter number : 75

Enter number : 436

Enter number : 1067

Enter number : 8

Enter number : 32

 

You have entered: 75, 436, 1067, 8, 32,

 

Notice how the value within brackets in the new statement is a variable value entered by the user (i), not a constant expression:

p= new (nothrow) int[i];

There always exists the possibility that the user introduces a value for i so big that the system cannot allocate enough memory for it. For example, when I tried to give a value of 1 billion to the "How many numbers" question, my system could not allocate that much memory for the program, and I got the text message we prepared for this case (Error: memory could not be allocated).

 

It is considered good practice for programs to always be able to handle failures to allocate memory, either by checking the pointer value (if nothrow) or by catching the proper exception.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
Object Oriented Programming and Data Structure : Data Abstraction & Overloading : Dynamic memory allocation |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.