Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----

Allocating Memory



Allocating memory for a single element


In the above examples a pointer held the address of an existing variable. We can also allocate memory dynamically ( that is at run time when the program is running ) and assign the address to a pointer. The size of the memory could be for say a single integer or even a block of 10 integers. In either case the pointer holds the address. In the case of a block the starting address of the block is stored in the pointer.

File: allocate1.cpp
#include <iostream>
using namespace std ;

int main()
{
    int* ptr1 ;
    //Allocating space a single int
    //Old style C way
    ptr1 = (int*)malloc( sizeof(int) * 1 ) ;
    *ptr1 = 100 ;
    cout << *ptr1 << endl ;
    free( ptr1 ) ;


    //new style of C++
    ptr1 = new int ;
    *ptr1 = 100 ;
    cout << *ptr1 << endl ;
    delete ptr1 ;


    return(0) ;
}
The above code shows how memory for a single int can be allocated on the heap dynamically.
ptr1 = (int*)malloc( sizeof(int) * 1 ) ;
We want to allocate memory for a single int . Remember "C++" is a super set of "C" and almost all of the "C" features are supported by "C++" . With "malloc" we have to specify the exact number of bytes that need to be allocated. The function
"sizeof(int)"
tells us the size of integer on this machine. Remember the sizes of a data type might be different depending on the computer hardware and the operating system. We are multiplying by 1 to explicitly show that we are only interested in 1 integer. We also
need to type cast with "(int*)" telling us what sort of memory has been allocated. In this case memory for a single int has been allocated. The type returned by "malloc" will always be a pointer holding an address. We may allocate space for a single integer or allocate space for a block of integers or even allocate space for a block of pointers.
Once we get the address we can place a value at the address with the statement:
*ptr1 = 100 ;
Once we are done with the pointer then we can free the memory that got allocated with the statement:
free( ptr1 ) ;
With "C++" we have similar calls but the syntax is much cleaner.
ptr1 = new int ;
The "new" system function call create a space for a single integer. In front of new we specify the type that we want to create the space for. There is no need to type cast it to a pointer. To free the memory we use:
delete ptr1 ;
Exercises
1) What is wrong with the following program ?
File: ex6.cpp
#include <iostream>
using namespace std ;



int main()
{
  int* ptr1 ;
  //new style of C++
  ptr1 = new int ;
  *ptr1 = 100 ;
  cout << *ptr1 << endl ;
  ptr1 =  ptr1 + 1 ;
  cout << *ptr1 << endl ;
  delete ptr1 ;

}

Allocating a block of Memory

Let's take a look at the below program:

File: allocate2.cpp
#include <iostream>
using namespace std ;


int main()
{
    int* ptr1 ;
    //Allocate space for 10 integers
    ptr1 = (int*)malloc( sizeof(int) *  10 ) ;
    ptr1[0] = 100 ;
    ptr1[1] = 200 ;
    cout << ptr1[0] <<  ":" << ptr1[1] << endl ;
    cout << *ptr1 <<  ":" << *(ptr1+1 )  << endl ;
    free( ptr1 ) ;


    //Allocating space the C++ way for 10 integers
    ptr1 = new int[10]  ;
    ptr1[0] = 101 ;
    ptr1[1] = 201 ;
    cout << ptr1[0] <<  ":" << ptr1[1] << endl ;
    cout << *ptr1 <<  ":" << *(ptr1+1 )  << endl ;
    delete[] ptr1  ;

    //int arr1[10 ] ;

    return(0) ;
}
Output:
100:200
100:200
101:201
101:201
The lines :
     //Allocate space for 10 integers

    ptr1 = (int*)malloc( sizeof(int) *  10 ) ;

    ptr1[0] = 100 ;

    ptr1[1] = 200 ;

    cout << ptr1[0] <<  ":" << ptr1[1] << endl ;

    cout << *ptr1 <<  ":" << *(ptr1+1 )  << endl ;

allocate a block of 10 integers . Conceptually our RAM diagram looks like:

                      RAM

               0

               1

   ptr1        2        6

               3

               4

               5

               6         ^

                         |    Block of

                         |     10 integers

                         |
Our pointer "ptr1" still holds as address . However this address now is the starting address of the block. We know we can access the value using "*ptr1" location. However we can also access the value using the array index notation.
cout << ptr1[0] << ":" << ptr1[1] << endl ;
cout << *ptr1 << ":" << *(ptr1+1 ) << endl ;
If we say "ptr1[0]" then we go to the address of "ptr1" and fetch the value there. It's the same exact thing as "*ptr" . Similarly if we say "ptr1[1]" that means go to where the address "ptr1" is and move 1 element down. It is the same as "*(ptr1+1)" . In fact arrays and pointers are almost the same thing in C++.
Exercises
1)
Explain what the below program does:
File: ex7.cpp
#include <iostream>
using namespace std ;



int main()
{
 int* ptr1 ;
 //Allocating space the C++ way for 10 integers
 ptr1 = new int[10]  ;
 for( int i1=0 ; i1<10 ; i1++ )
 {
        ptr1[i1]   =   i1   ;
        *( ptr1 + i1 )   +=   i1  ;
 } //for


 for( int i1=0 ; i1<10 ; i1++ )
 {
     cout << ptr1[i1] << endl  ;
 } //for

 delete[] ptr1  ;
 return(0) ;
}