Pointers and Dynamic Data

Pointers

Dynamic Memory Allocation

Allocating and Freeing Memory

Using assert

void assert(int test);
assert is a macro that expands to an if statement. If the test evaluates to 0, assert prints a message to stderr like this: Assertion failed: test, file , line
#include <assert.h>

void main(void)
{
  int* iPtr = new int[500000000]; // 500,000,000

  assert(iPtr != NULL);  
}
The output would look something like this:
  Assertion failed: iPtr != NULL, file driver.cpp, line 7	

Array Names are Pointers

The name of an array without the brackets is a pointer. The following code shows how to initialize an array of integers by calling the function initializeArray(...)

void main(void)
{
  int a[50];

  initializeArray(a, 50);  
}
The implementation of the function might look like this:
void initializeArray(int anArray[], int arraySize)
{
  for (int i = 0; i < arraySize; i++)
    anArray[i] = 0;
}
Or, it could be like this: (note that the function body doesn't change)
void initializeArray(int* anArray, int arraySize)
{
  for (int i = 0; i < arraySize; i++)
    anArray[i] = 0;
}
Declaring the formal parameter as int* anArray or as int anArray[] is the same to the compiler. Within the function, anArray points to the beginning of the actual array.

Modified Employee Class and Function

Recall our implementation of the setName function of the Employee class:

void Employee::setName(char first[], char last[])
{
  if (strlen(first) > 9)     // if too long, truncate
  {
    strncpy(firstName, first, 9);
    firstName[9] = '\0';
  }
  else
    strcpy(firstName, first);

  if (strlen(last) > 11)     // if too long, truncate
  {
    strncpy(lastName, last, 11);
    lastName[11] = '\0';
  }
  else
    strcpy(lastName, last);
}
We can modify the private data members to be pointers:
private:
    char* firstName;   // was char firstName[]
    char* lastName;    // was char lastName[]
and then implement the function this way:
void Employee::setName(char first[], char last[])
{
  firstName = new char[strlen(first) + 1];
  strcpy(firstName, first);

  lastName = new char[strlen(last) + 1];
  strcpy(lastName, last);
}

Modified Employee Class and Function (cont)

A more robust way would be like this:

void Employee::setName(char first[], char last[])
{

    // if firstName already allocated, free it
  if (firstName != NULL)
    delete [] firstName;

    // allocate room for the first name
  firstName = new char[strlen(first) + 1];

    // make sure the allocation succeeded
  assert( firstName != NULL);

    // copy the contents of the parameter to firstName
  strcpy(firstName, first);

    // if lastName already allocated, free it
  if (lastName != NULL)
    delete [] lastName;

    // allocate room for the last name
  lastName = new char[strlen(last) + 1];

    // make sure the allocation succeeded
  assert(lastName != NULL);

    // copy contents of the parameter to lastName
  strcpy(lastName, last);
}

Using Reference Types

int a = 25;      // a is 25
int& iRef = a;   // iRef is 25, a is 25
a = 15;          // a is 15, iRef is 15
iRef = 10;       // iRef is 10, a is 10

Reference Parameters in Functions

This function doesn't work correctly:

void SwapInt(int a, int b)
{
  int temp;

  temp = a;
  a = b;
  b = temp;
}
This function works correctly using pointers:
void SwapInt(int* a, int* b)
{
  int temp;

  temp = *a;
  *a = *b;
  *b = temp;
}
This function works correctly using reference parameters:
void SwapInt(int& a, int& b)
{
  int temp;

  temp = a;
  a = b;
  b = temp;
}

Using the & Operator (page 990)

Position       Usage                      Meaning
Prefix         &Variable                 Address-of operation
Infix          Expression & Expression   Bitwise AND operation
Infix          Expression && Expression  Logical AND operation
Postfix        DataType&                 Reference variable initialization
int a;
int* iPtr = &a;     // address-of operation
int& iRef = a;      // reference variable

if ( (a > 10) && ( a < 20) )   // logical AND
  doSomething();
Back to Outline