Broad Network


Dynamic Objects in C++

C++ Just After the Basics - Part 4

Forward: In this article I explain how C++ requests memory from free store for an object and how C++ returns the memory.

By: Chrysanthus Date Published: 22 Aug 2012

Introduction

Assume that you have your computer and it is currently running several programs. You can imagine the state of the memory as follows: Portions of the memory have been allocated to the different programs. Each portion belongs to one program. If there is any extra memory space, then that space is called, Free Store. As a program is running it can request a section of the free store; use it and then give it back when it has finished using it. The allocation and de-allocation of a piece of free store is controlled by the operating system.

Memory, be it free store or not, is always scarce, just like money is always scarce to humans. So when a program ask for a piece of free store, it should give it back when it has finished with it so that there would be free memory for other programs to use (ask for). If the program does not give it back, the part of the memory may remain blocked until the computer is shut down.

In this article I explain how a C++ program requests memory from free store for an object and how the memory is given. You need basic knowledge in C++ in order to understand this article. If you do not have that knowledge, then type, “Getting Started with C++” and my name Chrys in the search box of this page and click Search. That will take you to a series I wrote on C++ basics.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

Requesting and Returning Free Store Memory
C++ has the keywords, new and delete. These are operators, even though they might not look like operators. To request free store memory, the operator, new is used. To return the free store memory the operator, delete is used.

Objects and Free Store
An object is a region in memory that would hold a datum (e.g. an int) or a consistent set of data (e.g. an array). Note: an object is a region in memory. A free store object (also known as dynamic object) is an object that is created in free store. The objects you create the normal way in C++ are not free store objects, because they are not created in free store. There are three ways of creating a free store object.

Free store objects are accessed by pointers.

Single Object without Initialization of Object
The following statement illustrates how to create a free store object without initialization:

int *myIntPtr = new int;

For this statement the left operand declares the pointer that will point to an object of type int. The right operand begins with, new. new returns a pointer. After the operator, new, you have the object type specified. Other object types are created in free store in this way.

For the above statement, anywhere below in the code (in a function), you can assign value to the object pointed to by myIntPtr, like in,

        *myIntPtr = 5;

Single Object with Initialization of Object
You can create a free store object and at the same time initialize the object. The following statement illustrates this:

    int *myIntPtr = new int(42);

The statement is similar to the above except that the initial value for the pointed object is given in brackets just after the object type on the right of new. Other object types are created with initialization like this. If you are using the console, then you can send the value of the pointed object to the screen like in,

        cout << *myIntPtr;

An Array-Like Structure
You can create more than one consecutive objects of the same type in free store (dynamic memory). The following statement illustrates this:

    int *myIntPtr = new int[3];

Three consecutive empty int objects have been created in free store. Note the use of the square brackets just after int, after new. Inside the brackets, you put the number of consecutive objects that you want. Different types of consecutive objects of the same type are created like this. The pointer (myIntPtr) points to the first of the objects in the set. The pointer is not constant, so it can be incremented to point to the next object. It can also be decremented.

Anywhere below in the code (in a function), you can assign value to the first object of the set, like in,

        *myIntPtr = 10;

The following program shows how an array-like structure can be created in memory and be filled with values:

#include <iostream>
using namespace std;

int *myIntPtr = new int[3];

int main()
    {
        *myIntPtr = 10;
        ++myIntPtr;
        *myIntPtr = 20;
        ++myIntPtr;
        *myIntPtr = 30;
        cout << *myIntPtr<<"\n";
        --myIntPtr;
        cout << *myIntPtr<<"\n";
        --myIntPtr;
        cout << *myIntPtr<<"\n";

        return 0;
    }

In the code, after the second increment, the pointer is pointing to the third object. The cout statements display the values in reverse order by decrementing the pointer.

This and the preceding two sections give the three ways in which you can request (create) an object in free store.

Declaration or initialization of Pointer
Above, we have created the free store objects as follows:

    int *myIntPtr = new int;

    int *myIntPtr = new int(42);

    int *myIntPtr = new int[3];

In the second statement the pointed object is initialized. Well, that is initialization of the pointed object. In all the statements the pointer is initialized by a memory address (the pointer object is given an address of a pointed object in free store by, “new”). So we created the pointers by initializing the pointers (as opposed to declaring a pointer and then assigning an address later). Do not confuse between initializing the pointer and initializing the pointed object in free store. If you are creating your free store object in a function definition, then you can create the pointers by declaration before assignment as the following segments show:

    int *myIntPtr;
    myIntPtr = new int;

    int *myIntPtr;
    myIntPtr = new int(42);

    int *myIntPtr;
    myIntPtr = new int[3];

With this approach (in a function), you declare the pointer first before you assign the address.

Free Store Not Available
In the computer, it is not only your program that may want some of free store. Other programs might have been given parts of free store and free store might be exhausted (finished – all used up), by the time your program wants part of it.

The “new” operator returns a pointer. In the above code samples, myIntPtr is the identifier of an object that holds the address of a free store object. myIntPtr is a pointer. If free store is not available, “new” returns a null pointer. This is a pointer with an effective value of zero, not an address. When requesting memory, you should check if the free store object is created before you proceed to use the free store object. The following code illustrates this:

#include <iostream>
using namespace std;

int main()
    {
        char *myIntPtr;
        myIntPtr = new char;

        if (myIntPtr != NULL)
            {
                *myIntPtr = 'A';
                cout << *myIntPtr;
            }
        else
            {
                cout << "Free store not available";
            }

        return 0;
    }

Above, NULL identifies a null pointer. It comes from iostream under namespace std.
Read through the code.

Deleting Free Store Objects
You can request an object from Free Store and it would be granted. Conceptually, free store is under the control of the operating system. Well, after using the free store for an object, your program is responsible to deleting the object (so that other programs running can use the space). The following two statements will delete the int object created above:

        delete myIntPtr;
        delete [] myIntPtr;

The first delete statement is used to delete a single object, whether it was created with an initial value or not. The second is used for deleting the complete array structure and not just the first of the objects in the array. Note the position of the square brackets in the statement.

Dynamic Objects
Free store objects are created at run time, when the program is executed. A single free store object can be made to grow in the form of an array. The objects of the array should be of the same type. Free store objects are called Dynamic Objects.

Make a Single Object Grow
It is simple to make a single object grow. Just increment the pointer and use the new operator to assign the same object type from the free store to the incremented pointer. Like that you have an array of two objects of the same type, the first time you increment the pointer. If you want the length of the array to be three, increment the pointer again, use the new operator to assign the same object type from free store. Carry on like this for an array as long as you want. The following code illustrates this:

#include <iostream>
using namespace std;

int main()
    {
        int *myIntPtr;
        myIntPtr = new int;
        ++ myIntPtr = new int;
        ++ myIntPtr = new int;

        *myIntPtr = 30;
        -- myIntPtr;
        *myIntPtr = 20;
        -- myIntPtr;
        *myIntPtr = 10;

        cout << *myIntPtr << "\n";
        ++ myIntPtr;
        cout << *myIntPtr << "\n";
        ++ myIntPtr;
        cout << *myIntPtr << "\n";

        return 0;
    }

In the above code, the first int free store object is created. The second and third are created by incrementing the pointer. Remember, free store objects are pointed objects. The values of the pointed objects above, are filled as the pointer is decremented. The values are displayed, incrementing the pointer.

Normally you should check if free store is available before you create an object from it, when the pointer is incremented (an array here consists of fundamental objects). I have not done that check in the code samples of this article, especially the previous one above, because of time. In your commercial project, you should do that.

Dynamic Objects and Classes
Assume that you have a class called myClass. The following code segment will create a single object from the class in free store:

    myClass *myObjPtr;
    myObjPtr = new myClass;

You now have an object in free store instantiated from the class, myClass, pointed to by myObjPtr.

Assume that the class has a constructor method (function) and the constructor method can take the argument, (2,3).  The following code segment will instantiate an object in free store, initialized with the values 2 and 3.

    myClass *myObjPtr;
    myObjPtr = new myClass(2,3);

The object is instantiated from myClass and it is pointed to by myObjPtr. The following code segment will create an array structure in memory (free store) with three objects instantiated from myClass:

    myClass *myObjPtr;
    myObjPtr = new myClass[3];

The first object of the array is pointed to by myObjPtr.

Well, that is what I have prepared for dynamic objects. We continue in the next part of the series.

Chrys

Related Courses

C++ Course
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message