Dev Notes

Software Development Resources by David Egan.

C++ Pointers


C++, Pointers
David Egan

In C++, a pointer is an object whose value is the memory address of another object. In other words, a pointer is a variable which stored the memory address of another variable.

A pointer references a location in memory. When declaring a pointer, the type of the pointed-to variable must be specified:

int x = 5;
int * xPtr = &x; // Declare xPtr as a pointer to an int x, referenced by the address of x.

double y = 5.55;
double * yPtr = &y; // Declare yPtr as a pointer to a double y, referenced by the address of y.
...

Specifying type when declaring a pointer is necessary because when the pointer is dereferenced (i.e. the pointed-to value is accessed) the type needs to be known.

Dereferencing

To access the value held in the memory address held by a pointer, the pointer is dereferenced using the * operator - the same operator used to declare a pointer variable:

int main(int argc, char const *argv[])
{
    int x = 5; // assign a value to integer variable x
    int * ptr = &x; // Assign the address of x to integer pointer ptr
    std::cout << *ptr << std::endl; // Output the pointed-at value - in this case, 5;
    ...
}

Pointer Access

For:

int x = 5;
int * ptr = &x;

…the following holds:

Variable Output
ptr Returns the address that ptr points to: 0x7fff829afe04
&ptr Returns the pointer’s own address, the address of ptr: 0x7fff829afe08
*ptr Dereference the pointer ptr - return the value held at the address held (pointed-to) by ptr: 5
&x Return the address of x: 0x7fff829afe04
*&ptr Dereference the address of ptr - return the value held in the address of ptr: 0x7fff829afe04
*&x Dereference the address of x, returns the value held in the address of x: 5

Pointer to Pointer

Pointers generally contain the memory address of a variable - but they can also contain the address of another pointer.

int main () {
  int num = 10;
  int *numPtr = &num; // Pointer to num
  numPtrPtr = &numPtr; // Pointer to pointer

  std::cout << "Value of num : " << num << std::endl; // Outputs 10
  std::cout << "Dereference numPtr: " << *numPtr << std::endl; // Outputs 10
  std::cout << "Dereference numPtrPtr: " << **numPtrPtr << std::endl; // Outputs 10

  return 0;
}

Using a pointer-to-pointer as a function parameter makes it possible to modify values within a function with those values persisting outside the function.

It is not likely that you need to use pointer-to-pointer type structures in modern C++ code. References are available for passing to a function by reference rather than value, and rather than pointing to an array of strings, it’s probably better to use std::vector<std::string>. However, the char ** notation does pop up - I recently saw this while researching the C getopt() function - in which an example showed arguments to the main() function are presented as char **argv, rather than the more common char char *argv[].

Pointer to Pointer/Pointer to char * array Equivalence

A sequence of strings can be passed to main() as an argument, if the main function is able to receive them.

You give main() the capacity to receive arguments by adding two parameters to the function - an int and a pointer to char.

The following are equivalent:

/**
 * Declare argv as array of pointer to char
 */
int main(int argc, char * argv[])
{
  // Loop through parameters
  for (size_t i = 0; i < argc; i++) {
        std::cout << "argv[" << i << "]: " << argv[i] << std::endl;
  }
}

/**
 * Declare argv as pointer to pointer to char
 * This declaration is valid - as far as I can tell, it is less common in C++.
 */
int main(int argc, char **argv)
{
  // Access arguments in the same way as above.
}

Because char *argv[] is read ‘declare argv as array of pointer to char’, and the array argument is demoted to a pointer to the first element in that array, char *argv[] is equivalent to char **argv - which is read as: ‘declare argv as pointer to pointer to char’

References


comments powered by Disqus