Memory Management Part 1: An Introduction To Pointers.

Now, there is an inconvenient truth to programming that many do fail to catch if they are using Java and other garbage collected languages and it is that memory must be managed effectively. While newer languages use garbage collection, C, C++, and many other languages still utilize manual memory management. Also, manual memory management can sometimes be notably better than garbage collection in terms of performance. The reason for this is that the garbage collector has to determine what objects can be removed which adds processing overhead and sometimes can stall a program temporarily if the collector isn't concurrent, real-time, or incremental. There is also the possibility that if the garbage collector is not well handled, it can often fail to catch when items in memory are no longer necessary. It is for these reasons that I strongly recommend that people understand pointers and how to manage memory.

Now that I have explained the importance of understanding memory management, I will introduce how pointers work. The most basic idea of pointers is that it points to a particular part of memory where information is stored. Now usually when a variable is declared, it is assigned a position in memory automatically without us having to do it thanks in part to the operating system. However, it is useful to know the position of some variables. To get this we would use a reference operator, which in C and C++ is represented by the ampersand sign (&) prior to a variable name. Below is an example that I will explain.

addressOne = &one;

In the example line of code I have given, the variable addressOne is being set to the address that the variable one is held rather than what one holds. As a result, when addressOne is printed, it will show the address of one. We can use addressOne to access the information held in one though by using a dereference operator which is represented by an asterisk (*) prior to a variable name. Below is an example of this in action:

newOne = *addressOne;

In the example I have given, newOne is being set to the value held in addressOne's address. With all of this in mind, I will combine these examples together with a value.

int one = 42;
addressOne = &one;
newOne = *addressOne;

In this example, one and newOne would be set to the integer 42 and addressOne would be set to the address that holds the value of the one variable. Likewise, should I not have had the dereference operation in front of addressOne and went 'newOne = addressOne' then newOne would contain the address that one is set to and not the actual integer. In addition to this, pointer types can be declared straight out of the gate by using the following syntax in C/C++:

int * two;

In this respect, the asterisk is actually behaving differently as it is declaring this to be a pointer and is not acting as a dereference operator as we've seen before. Instead of this being an integer though, this states that this holds the address of an integer and it will function to mention what type of value it is supposed to hold typically.

Last, but certainly not least is that there is a more advanced trick that allows you to use function pointers. What this consists of is creating variables that point to an executable function. The way to establish a function pointer is seen below:

int (*doublerPointer)(int);

In the example I have given, this establishes a function pointer named doublerPointer, mentions that it receives one integer, and that it returns an integer. Now let's say that I want to use it with a function such as this:

int doubler(int input)
     return input * 2;

This would require me to set this to the location of this function. An example of this being used to double a number is shown below.

int (*doublerPointer)(int);
doublerPointer = doubler;
int result = (*doublerPointer)(4);

The end result of this example would be that result would end up being 16. Now in the case of this, the best use of function pointers are for using them in a callback function that will handle more than one function pointer that utilize the same types of input and output. As such, I would recommend using it for just that and for other specialized tasks where function pointers would be superior over simply calling the function.