Tutorials 
navigation
The DOs and DON'Ts of Pointers
BASIC OVERVIEW
  1. Pointers are usually indicated by using the '*' symbol before the variable name. To declare a pointer the syntax is,
    [variable type] * [variable name];
    int *p;
    as an example.

  2. Pointers need to point to a variable of the same type. So if you declare int pointer, it will either need to reference another int pointer or the address of an int variable. Here is an example of an int pointer referencing the address of an int variable. The '&' symbol means address.
    int v;
    int *p;
    p = &v;

  3. Here is an example of an int pointer referencing another int pointer.
    int v = 6;
    int *p1 = &v;
    int *p2;
    p2 = p1;

  4. Dereferencing also uses the '*' symbol. What dereferencing does is if your pointer points at a variable, when you dereference the pointer you can retrieve the value of the variable or alter the variable. Here is an example of dereferencing a pointer so that you can retrieve the value of the variable.
    int v = 5;
    int *p = &v;
    if(*p == 5)
       v = 6;

  5. Here is an example of dereferencing a pointer so that you can alter the value.
    int v;
    int *p = &v;
    *p = 6; // Actually changes v.

  6. The main importance of pointers is the ability to dynamically create new instances of objects. The 'new' keyword is used to create a variable in memory. It's really important to make pointers point to dynamic copies. If a reference is lost to a new variable, it turns into a memory leak in your application. Here is an example of the 'new' and 'delete' keywords. 'delete' just helps us clean up the new variable so we don't get memory leaks. 'NULL' is the same as zero.
    int *p = new int(); // Makes new int in memory.
    delete p; // Removes the new int from memory.
    p = NULL; // Make sure we don't access the old int address.

  7. An advantage to using pointers is the ability to dynamically create arrays. With a standard array you are stuck with creating a fixed size. With a pointer array, you can dynamically create almost any size you want. In the previous example we dynamically created a single int with 'new int()'. We can create a pointer array by inserting a number between the parenthesis like 'new int(100)'. The cleanup is a little different because we use array syntax '[100]'. The 100 is optional, so you have the option to just use '[]'.
    int *p = new int(100); // Dynamically creates an 100 element int array.
    delete [100]p; // Explicitly removes all 100 elements from the array.
    p = NULL; // Make sure we don't access the old int address.
DON'T
Dereferencing is common with pointers. A mistake that is often made is setting a value to a dereferenced pointer before that pointer has been initialized.

int i = 2;

int *p;

*p = i;

DON'T
The compiler can catch a lot of your mistakes, but it won't catch one's like these. This problem is similar to the one above. This time the pointer has been initialized, but not with an address of a variable that can hold its data type.

int i = 2;

int *p = 0; // Initialized, but not pointing to an address

*p = i;

DON'T
The same problem happens if we initialize the pointer to a non address and try to set a value to that dereferenced pointer.

int i;

int *p = 0; // Initialized, but not pointing to an address

*p = 2;

DON'T
The same problem happens if we initialize the pointer to a non address and try to set a value to that dereferenced pointer. Here's another look of the same error.

int i;

int *p = NULL; // Initialized, but not pointing to an address

*p = 2;

DO
If you are going to initialize your pointers, you need to use a real address. This is how you do it.

int i;

int *p = &i;

DO
Here is an example of how to properly set a value to your dereferenced pointer, step by step.

int i;

int *p;

p = &i;

*p = 2; // This actually sets i to 2.

DO
Here is an example of how to properly set a value to your dereferenced pointer, in fewer steps.

int i;

int *p = &i;

*p = 2; // This actually sets i to 2.

DON'T
When you use a static pointer, you can run into memory issues. This problem results in how static works. The first time the code is executed is when the static pointer is set. The second time the code is reached, the local variables will have different memory addresses causing a memory error.

int i = 2;

static int *p = &i;

*p = 1234; // crashes on second lap because i has a different

           // memory address each time this code executes.

  /*

	There are 3 easy solutions to this problem.

	(1) Don't make p static

	(2) Make i static

	(3) Correct the code by splitting it into two statements:

		int i = 2;

		static int *p;

                p = &i;

		*p = 1234;

  */

DO
When working with pointers, type casting is always good so you know what kind of objects you are working with.

int i;

int *p = (int*)&i;

*p = 1;

DO
The memset function is commonly used with pointers. It helps us be sure that memory was allocated when we made our variables. Here is an example of how to use it.

#include  // let's us use the memset function

//...

int i;

if( memset(&i, 0, sizeof(int)) )

   return -1; // Memory was not allocated

DO
The memcpy function is commonly used with pointers. It helps us be sure that memory was copied properly when we do an assignment. Here is an example of how to use it.

#include  // let's us use the memset function

//...

int i = 6;

int j;

if( i != *(int*)(memcpy(&j, &i, sizeof(int))) )

   return -1; // Memory was not allocated

DO
In more advanced concepts of C++, ADTs (Abstract Data Types) are used. Most implementations require lists of some kind. In order to construct your own list without using arrays, you will need to use pointers. To make your own objects you can use struct or class. Both have data members and methods. For a list implementation, your object will need a pointer to the same type of object to link them together. Here is a brief example of that kind of situation. This is a basic structure object with a Value data member and a pointer to let us create a list. Elements in abstract lists are commonly referred to as nodes. You'll see that Node is a pointer with the same type as the object that it is part of. This is intentional. We want our list elements to be able to point to other elements in the list. It makes sense that all the elements in the list would be the same type of elements.

 struct aMyArray

 {

 public:

    int Value;

    aMyArray *Node;

 }