View page as slide show

Pointers 4 slides

Dynamic memory, memory management, pointers as return types.1)
Mithat Konar
October 23, 2021

Dynamic memory allocation

The new operator

double *foo;      // pointer to a double
foo = new double; // allocate an unnamed block of memory
                  // large enough to hold a double
                  // and set foo to point to it.

Example

simple-allocation.cpp
/** Dynamically allocate and use two doubles. */
#include <iostream>
using namespace std;
 
int main()
{
    double *myPtr, *yourPtr;
 
    myPtr = new double;
    yourPtr = new double;
 
    cout << "Enter a number: ";
    cin >> *myPtr;
    cout << "Enter a number: ";
    cin >> *yourPtr;
 
    cout << "The average of the two numbers is " << (*myPtr + *yourPtr)/2.0 << "." << endl;
 
    return 0;
}

Dynamic allocation of arrays

dynamic-array.cpp
/** Dynamically allocate and use an array. */
#include <iostream>
using namespace std;
 
int main()
{
    const int SIZE = 10;
    double *arrayPtr = new double[SIZE];  // create block to hold array
 
    /* You can use subscript notation [] to access an array: */
    for(int i = 0; i < SIZE; i++)
    {
        arrayPtr[i] = i * i;
    }
 
    /* or pointer arithmetic: */
    for(int i = 0; i < SIZE; i++)
    {
        cout << *(arrayPtr + i) << endl;
    }
 
    return 0;
}

Memory Management

Memory management of regular variables

local-var-memory.cpp
/** Example showing local variable lifetime. */
#include <iostream>
using namespace std;
 
void ninetynine();
 
int main()
{
    ninetynine();
 
    // ... do some other stuff ... //
 
    return 0;
}
 
void ninetynine()
{
    int localVar = 99;  // localVar is destroyed at end of fcn call
    cout << localVar << endl;
}

Memory management of dynamically allocated storage

memory-loss.cpp
/** Example showing lifetime of dynamically allocated storage and a 
  * a small memory leak.
  */
#include <iostream>
using namespace std;
 
void ninetynine();
 
int main()
{
    ninetynine();
 
    // ... do some other stuff ... //
 
    return 0;
}
 
void ninetynine()
{
    int *localPtr = nullptr;  // localPtr is destroyed at end of fcn call
    localPtr = new int;       // but not dynamically allocated storage
 
    *localPtr = 99;
    cout << *localPtr << endl;
}

Memory leaks

memory-leak.cpp
/** Example of a sizable memory leak. */
#include <iostream>
using namespace std;
 
void ninetynine();
 
int main()
{
    for (int i=0; i<10000; i++)
    {
        ninetynine();
    }
 
    // ... do some other stuff ... //
 
    return 0;
}
 
void ninetynine()
{
    int *localPtr = new int;
 
    *localPtr = 99;
    cout << *localPtr << endl;
}

Memory leaks

The delete operator

int *myPtr = new int;
...
delete myPtr; // deallocates block pointed to by myPtr.

Example

The code below fixes the memory leak introduced above:

deallocation.cpp
/** Example showing deallocation. */
#include <iostream>
using namespace std;
 
void ninetynine();
 
int main()
{
    ninetynine();
 
    return 0;
}
 
void ninetynine()
{
    int *localPtr = new int;
 
    *localPtr = 99;
    cout << *localPtr << endl;
    delete localPtr;  // deallocates block pointed to by localPtr.
}

Deallocating arrays

Use square brackets to deallocate dynamically allocated arrays: delete [] arrayPtr;

Gaddis-Pr9-14.cpp
// This program totals and averages the sales figures for any
// number of days. The figures are stored in a dynamically
// allocated array.
#include <iostream>
#include <iomanip>
using namespace std;
 
int main()
{
    double *sales = nullptr,    // To dynamically allocate an array
    total = 0.0,                // Accumulator
    average;                    // To hold average sales
    int numDays,                // To hold the number of days of sales
        count;                  // Counter variable
 
    // Get the number of days of sales.
    cout << "How many days of sales figures do you wish ";
    cout << "to process? ";
    cin >> numDays;
 
    // Dynamically allocate an array large enough to hold
    // that many days of sales amounts.
    sales = new double[numDays];
 
    // Get the sales figures for each day.
    cout << "Enter the sales figures below.\n";
    for (count = 0; count < numDays; count++)
    {
        cout << "Day " << (count + 1) << ": ";
        cin >> sales[count];
    }
 
    // Calculate the total sales
    for (count = 0; count < numDays; count++)
    {
        total += sales[count];
    }
 
    // Calculate the average sales per day
    average = total / numDays;
 
    // Display the results
    cout << fixed << showpoint << setprecision(2);
    cout << "\n\nTotal Sales: $" << total << endl;
    cout << "Average Sales: $" << average << endl;
 
    // Free dynamically allocated memory
    delete [] sales;
    sales = nullptr; // Make sales a nullptr.
 
    return 0;
} 

heap vs. stack

''malloc'' and ''free''

Returning Pointers from Functions

A function can return a pointer:

returned-pointer.cpp
/** Returning a pointer from a function. */
#include <iostream>
using namespace std;
 
char* someChar();
 
int main()
{
    char *foo;
 
    foo = someChar();
 
    cout << *foo << endl;
 
    return 0;
}
 
char* someChar()
{
    char *myCharPtr = new char;
 
    *myCharPtr = 'a';
 
    return myCharPtr;
}

Returning Pointers from Functions

Example

Gaddis-Pr9-15.cpp
// This program demonstrates a function that returns
// a pointer.
#include <iostream>
#include <cstdlib>   // For rand and srand
#include <ctime>     // For the time function
using namespace std;
 
// Function prototype
int *getRandomNumbers(int);
 
int main()
{
   int *numbers;  // To point to the numbers
 
   // Get an array of five random numbers.
   numbers = getRandomNumbers(5);
 
   // Display the numbers.
   for (int count = 0; count < 5; count++)
      cout << numbers[count] << endl;
 
   // Free the memory.
   delete [] numbers;
   numbers = 0;
   return 0;
}
 
//**************************************************
// The getRandomNumbers function returns a pointer *
// to an array of random integers. The parameter   *
// indicates the number of numbers requested.      *
//**************************************************
 
int *getRandomNumbers(int num)
{
   int *arr = nullptr;	// Array to hold the numbers
 
   // Return null if num is zero or negative.
   if (num <= 0)
      return NULL;
 
   // Dynamically allocate the array.
   arr = new int[num];
 
   // Seed the random number generator by passing
   // the return value of time(0) to srand.
   srand( time(0) );
 
   // Populate the array with random numbers.
   for (int count = 0; count < num; count++)
      arr[count] = rand();
 
   // Return a pointer to the array.
   return arr;
}

Smart Pointers

unique_ptr<type_pointed_to> pointer_name( expression_to_allocate_memory )

Example

ptr will be automatically deleted when the function returns.

Gaddis-Pr9-17.cpp
// This program demonstrates a unique_ptr.
#include <iostream>
#include <memory>
using namespace std;
 
int main() 
{
   // Define a unique_ptr smart pointer, pointing
   // to a dynamically allocated int.
   unique_ptr<int> ptr( new int );
 
   // Assign 99 to the dynamically allocated int.
   *ptr = 99;
 
   // Display the value of the dynamically allocated int.
   cout << *ptr << endl;
   return 0;
}

Example

Dynamically allocating a large block of managed memory.

Gaddis-Pr9-18.cpp
// This program demonstrates a unique_ptr pointing
// to a dynamically allocated array of integers.
#include <iostream>
#include <memory>
using namespace std;
 
int main() 
{
   int max;   // Max size of the array
 
   // Get the number of values to store.
   cout << "How many numbers do you want to enter? ";
   cin >> max;
 
   // Define a unique_ptr smart pointer, pointing
   // to a dynamically allocated array of ints.
   unique_ptr<int[]> ptr( new int[max]);
 
   // Get values for the array.
   for (int index = 0; index < max; index++)
   {
      cout << "Enter an integer number: ";
      cin >> ptr[index];
   }
 
   // Display the values in the array.
   cout << "Here are the values you entered:\n";
   for (int index = 0; index < max; index++)
      cout << ptr[index] << endl;
 
   return 0;
}

Other smart pointers

1)
Portions adapted from: Gaddis, Tony. “Pointers.” In Starting Out with C++: From Control Structures through Objects. 8th ed. Boston: Pearson, 2015. 495-546.