Home

Pointers and Memory Management

 

Introduction

Imagine you write the following program:

using namespace System;

int main()
{
    typedef double Salary;

    Salary Monthly;
    Salary Hourly, Weekly;
    double WeeklyHours;

    return 0;
}

When your program launches, that is, when it loads in the computer memory, the compiler reserves an appropriate amount of space in the heap memory for each declared variable. This technique of providing memory space is called static allocation, the memory space is "allocated" to that variable. Just after the program has launched and memory has been allocated (or assigned) to each variable, each memory space is filled 0. Check it with the following program:

using namespace System;

int main()
{
    typedef double Salary;

    Salary Monthly;
    Salary Hourly, Weekly;
    double WeeklyHours;
	
    Console::WriteLine("Employee Payroll");
    Console::Write("Weekly Hours:   ");
    Console::WriteLine(WeeklyHours);
    Console::Write("Hourly Salary:  ");
    Console::WriteLine(Hourly);
    Console::Write("Weekly Salary:  ");
    Console::WriteLine(Weekly);
    Console::Write("Monthly Salary: ");
    Console::WriteLine(Monthly);

    return 0;
}

This would produce the following warnings:

warning C4700: uninitialized local variable 'WeeklyHours' used
warning C4700: uninitialized local variable 'Hourly' used
warning C4700: uninitialized local variable 'Weekly' used
warning C4700: uninitialized local variable 'Monthly' used

It would display the following:

Employee Payroll
Weekly Hours:   0
Hourly Salary:  0
Weekly Salary:  0
Monthly Salary: 0

Press any key to continue

As you can see, the memory allocated to each variable is filled with a 0 value. If you decide to use a pointer to a variable, you can declare and initialize such a variable. This system of declaring and initializing a pointer also allows the compiler to allocate a memory space for the pointer in the heap. Remember, just like a regular variable, a pointer is also a variable and uses its own memory space. This pointer can also be assigned a value that would be shared with the pointed to variable:

using namespace System;

int main()
{
    typedef double Salary;

    Salary Monthly;
    Salary Hourly, Weekly;
    double WeeklyHours;
    double *PHourly;
	
    Hourly = 12.55;
    WeeklyHours = 42.50;
	
    PHourly = &Hourly;

    Weekly = Hourly * WeeklyHours;

    Console::WriteLine("Payroll Preparation");
    Console::WriteLine("Enter Employee's Weekly Hours: ");

    Console::WriteLine("Employee Payroll");
    Console::Write("Weekly Hours:   ");
    Console::WriteLine(WeeklyHours);
    Console::Write("Hourly Salary:  ");
    Console::WriteLine(*PHourly);
    Console::Write("Weekly Salary:  ");
    Console::WriteLine(Weekly);
    Console::Write("Monthly Salary: ");
    Console::WriteLine(Monthly);

    return 0;
}

This would produce:

Payroll Preparation
Enter Employee's Weekly Hours:
Employee Payroll
Weekly Hours:   42.5
Hourly Salary:  12.55
Weekly Salary:  533.375
Monthly Salary: 0
Press any key to continue . . .

Notice that the Monthly variable is still holding 0 and it has not been used throughout the program.

The new Operator

Instead of letting the compiler provide memory when your program comes up, you can ask it to use memory only when necessary. In that case, the compiler would allocate memory when the program is executing. This is called dynamic allocation. Dynamic allocation allows you to use memory "as needed" and not "as required".

To dynamically assign memory, the C++ language provides the new operator. Here is the syntax to use it:

PointerName = new DataType;

The PointerName must be a declared pointer. You could have declared it previously or you can declare it when performing memory allocation.

The assignment operator "=" and the new keyword are required. they let the compiler know that you are about to request memory.

The DataType parameter can be any of those we are already familiar with, but it must be the same as the variable it is pointing to. This means that, if PointerName points to an integer variable, the data type must be an integer:

using namespace System;

int main()
{
    typedef double Salary;

    Salary Monthly;
    Salary Hourly, Weekly;
    double WeeklyHours;
    double *PHourly;
	
    Hourly = 12.55;
    WeeklyHours = 42.50;
	
    PHourly = &Hourly;
    *PHourly = 14.25;

    Weekly = Hourly * WeeklyHours;

    Console::WriteLine("Payroll Preparation");
    Console::WriteLine("Employee Payroll");
    Console::Write("Weekly Hours:   ");
    Console::WriteLine(WeeklyHours);
    Console::Write("Hourly Salary:  ");
    Console::WriteLine(*PHourly);
    Console::Write("Weekly Salary:  ");
    Console::WriteLine(Weekly);
    Console::Write("Monthly Salary: ");
    Console::WriteLine(Monthly);

    PHourly = new double;

    return 0;
}

Whenever you (decide to) dynamically allocate memory to a pointer variable, if the pointer had been previously initialized, the value that was stored in that pointer is lost (obsolete). Furthermore, if the pointer was pointing to an already declared variable, the relationship is broken: the pointer would not point to that variable anymore. In other words, both the pointer and the variable it was pointing to do not hold the same value anymore. The pointed to variable keeps its value because it is independent from the pointer (it is the pointer that is pointing to the variable and not vice-versa).

Practical LearningPractical Learning: Introducing Pointers

  1. To start a new program, launch Microsoft Visual C++ 2005
  2. On the main menu, click File -> New -> Project...
  3. On the left side, make sure that Visual C++ is selected. In the Templates list, click CLR Empty Project
  4. In the Name box, replace the string with RealEstate3 and click OK
  5. To create a source file, on the main menu, click Project -> Add New Item...
  6. In the Templates list, click Source File (.cpp)
  7. In the New box, type Exercise and click Add
  8. In the empty file, type:
     
    using namespace System;
    
    int main()
    {
        long *propertyNumber    = new long;
        __wchar_t *propertyType = new __wchar_t;
        Byte *stories           = new Byte;
        unsigned int *bedrooms  = new unsigned int;
        float *bathrooms        = new float;
        unsigned int *yearBuilt = new unsigned int;
        double *marketValue     = new double;
    
        *propertyNumber = 204755;
        *propertyType   = 'C';
        *stories = 1;
        *bedrooms  = 2;
        *bathrooms = 2.0F;
        *yearBuilt = 2002;
        *marketValue = 248550;
    
        Console::WriteLine("=//=  Altair Realty  =//=");
        Console::WriteLine("-=- Properties Inventory -=-");
        Console::Write("Property #:    ");
        Console::WriteLine(*propertyNumber);
        Console::Write("Property Type:  ");
        Console::WriteLine(*propertyType);
        Console::Write("Stories:        ");
        Console::WriteLine(*stories);
        Console::Write("Bedrooms:       ");
        Console::WriteLine(*bedrooms);
        Console::Write("Bathrooms:      ");
        Console::WriteLine(*bathrooms);
        Console::Write("Year Built:     ");
        Console::WriteLine(*yearBuilt);
        Console::Write("Market Value:   ");
        Console::WriteLine(*marketValue);
        
        return 0;
    }
  9. To execute the application, on the main menu, click Debug -> Start Without Debugging
     
    =//=  Altair Realty  =//=
    -=- Properties Inventory -=-
    Property #:    490724
    Property Type:  S
    Stories:        2
    Bedrooms:       5
    Bathrooms:      3.5
    Year Built:     1962
    Market Value:   652540
    Press any key to continue . . .
  10. Close the DOS window

The delete Operator

After dynamically allocating memory, you can assign a new value to the pointer for any purpose. Once the memory is not in use anymore, you should reclaim it. This is done with the delete operator. The formula to use it is:

delete PointerName;

The delete keyword is required. It lets the compiler know that you do not want to use the pointer anymore.

The PointerName is the name of the pointer that was dynamically allocated with the new operator. You cannot use the delete operator if you did not previously use the new operator to allocate memory.

To use the delete operator, simply type delete followed by the name of the pointer whose memory you want to reclaim. This operation is referred to as deallocating the memory (you are deallocating the memory that was dynamically allocated):

using namespace System;

int main()
{	
    double * PHourly = new double;

    Console::WriteLine("Stuff...");

    delete PHourly;

    return 0;
}

Practical LearningPractical Learning: Deleting Pointers

  1. To de-allocate the memory previously used by the variables, change the file as follows:
     
    using namespace System;
    
    int main()
    {
        long *propertyNumber    = new long;
        __wchar_t *propertyType = new __wchar_t;
        Byte *stories           = new Byte;
        unsigned int *bedrooms  = new unsigned int;
        float *bathrooms        = new float;
        unsigned int *yearBuilt = new unsigned int;
        double *marketValue     = new double;
    
        *propertyNumber = 204755;
        *propertyType   = 'C';
        *stories = 1;
        *bedrooms  = 2;
        *bathrooms = 2.0F;
        *yearBuilt = 2002;
        *marketValue = 248550;
    
        Console::WriteLine("=//=  Altair Realty  =//=");
        Console::WriteLine("-=- Properties Inventory -=-");
        Console::Write("Property #:    ");
        Console::WriteLine(*propertyNumber);
        Console::Write("Property Type:  ");
        Console::WriteLine(*propertyType);
        Console::Write("Stories:        ");
        Console::WriteLine(*stories);
        Console::Write("Bedrooms:       ");
        Console::WriteLine(*bedrooms);
        Console::Write("Bathrooms:      ");
        Console::WriteLine(*bathrooms);
        Console::Write("Year Built:     ");
        Console::WriteLine(*yearBuilt);
        Console::Write("Market Value:   ");
        Console::WriteLine(*marketValue);
        
        delete propertyNumber;
        delete propertyType;
        delete stories;
        delete bedrooms;
        delete bathrooms;
        delete yearBuilt;
        delete marketValue;
    
        return 0;
    }
  2. Execute the application to see the result
  3. Close the DOS window
 

Previous Copyright © 2006 FunctionX, Inc. Next