GreySec Forums

Full Version: [Tutorial] Intro to Pointers
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Alright, lets talk about pointers...actually first, lets talk about variables and memory.

A variable is something that has a value that can vary through-out a programs execution and it is stored in memory.

Memory, think of it like a notebook. When your program starts it'll fill in the notebook with any data it knows its going to need at the start. This is stuff like any hard-coded values or "strings" in your program will be written in there at the start. There is a pattern to how and where it writes pieces of data depending on how they are declared in the program but I won't be going into such details. What matters is that the program stores all this information in the notebook/memory.

Every variable you create has the value assigned to it stored somewhere in this notebook.

So, say you wanted to show your friend this really awesome number you stored in one of your variables. You have two options, you can simply tell your friend the number: "Thirty-one is a cool number!", or you can tell them where to find the number in your notebook: "Check the first line of page four"

In the first case when you just tell your friend the number you're basically duplicating the data it works great for small stuff, but what if instead of a number you wanted your friend to proof-read your paper. You could read it out to them, but then any changes they try to make will be on their copy of it. Instead you'd want to show them where the paper to be proofread is in your notebook and they can make changes to it there.

In these examples, a pointer is the second case. A pointer is just that, it points you to where something is stored. In the case of your program, a pointer is just a number that corresponds to where in your programs memory space(notebook) the value begins.

So now you know what a pointer is, but pointer types are still a little tricky.

Code:
int x = 5;
int* ptr = &x;//& means the address of, so &x means the address of the variaible x


In the above code we have the variaible x which gets the value 5. We also have another line though, its a pointer type but its also a variaible. That means the value we assign to ptr gets stored somewher in memory also. It just so happens that at this place in memory we are storing the address to another piece of memory. Remember, the address to a computer is just a number that happens to correspond to a place in memory, so int* ptr is  storing a number just like int x is. The only special thing is that we told the compiler that the number we store in ptr is special as it points to where something else is stored. Otherwise the int* and int are pretty much the same.

Code:
int x = 5;
int* ptr = &x;
int** ptr2 = &ptr;
int*** ptr3 = &ptr2;
...

We can carry this on, since int* is just a variable storing a value, int** ptr2 is just a variable storing a value also, its value happens to be the address of the int* ptr which happens to be the address of int x. At the core, pointers are just normal ole integers.

So why do we even call them pointers if they work just like normal variables? Well we do that so the compiler understands the type of data we have. When it knows we are working with a pointer to somewhere in memory we can instruct it to operate on the data being pointed to:

Code:
int x = 5;
int* ptr = &x;
*ptr = 22;

That code, because the compiler understands ptr is a pointer, when we tell it to access *ptr and assign it a value it knows to actually operate on the memory being pointed to by ptr and not the value of ptr itself.

Lets consider some example code for a game

Code:
#include <stdio.h>

void left(int x, int y) {
    x = x - 1;
}
void right(int x, int y) {
    x = x + 1;
}
void up(int x, int y) {
    y = y + 1;
}
void down(int x, int y) {
    y = y - 1;
}

int main() {
    int x = 10;
    int y = 10;
    printf("You are now at (%d,%d)\n",x,y);
    left(x,y);
    left(x,y);
    up(x,y);
    right(x,y);
    down(x,y);
    printf("You are now at (%d,%d)\n",x,y);
}

After this code runs, what should it print out? If you guessed

Code:
You are now at (10,10)
You are now at (10,10)

Then you're correct, that is because the x and y the movement functions are acting upon are copies of the original values. If we want to work on the original values we need to give the functions pointers to where they are stored. That way the function itself can modify the players x and y coordinates.

Code:
#include <stdio.h>

void left(int* x, int* y) {
    *x = *x - 1;
}
void right(int* x, int* y) {
    *x = *x + 1;
}
void up(int* x, int* y) {
    *y = *y + 1;
}
void down(int* x, int* y) {
    *y = *y - 1;
}

int main() {
    int x = 10;
    int y = 10;
    printf("You are now at (%d,%d)\n",x,y);
    left(&x,&y);
    left(&x,&y);
    up(&x,&y);
    right(&x,&y);
    down(&x,&y);
    printf("You are now at (%d,%d)\n",x,y);
}

This time the functions take pointers to the int so they can move the player on their own. So what should the output be?

Code:
You are now at (10,10)
You are now at (10,9)

Of course you might be thinking what don't I just utilize return values?

Code:
x = left(x,y);
y = up(x,y);
[code]

Of course that will work in these simple cases, but what if I wanted to implement diagonal moves?

[code]
??? upleft(int x, int y) {
    x = x - 1;
    y = y + 1;
    return ???
}

What do you return then? If you use pointers this isn't a problem you can pass the function all the data it needs to operate on

Code:
void upleft(int* x, int* y) {
    *x = *x - 1;
    *y = *y + 1;
}
upleft(&x,&y);

Pointers made it possible to cleanly do this.

This isn't a very complete guide to pointers there are many more nuances when you start dealing with arrays vs pointers and their differences but this should hopefully give you an understanding of what a pointer is and how they can be used.
Very interesting tutorial, nice work dropzone! Despite having known about C++ and studying it at school I've only known the basics. Never knew about pointers or how they work, so I learned something new. I will see if I can find a good use for these functions.
I ctrl-F'd scope and didn't see you talk about that so I'd think that'd be rather important. I also think you textually compared pointers and variables a bit too strongly, although your examples are correct. a pointer contains a memory location just like you said, however they are not identical to variable values. Everything is stored in memory somewhere.

Code:
int a = 5; //a is stored in 0x5000 but if you reference 'a', you will get 5.
int* b = &a; //b is a pointer to the memory location 0x5000. If you reference 'b', you will get 20480 (0x5000)

Overall, nice article.
Quote:I ctrl-F'd scope and didn't see you talk about that so I'd think that'd be rather important.

I avoided that intentionally, you might noticed I never used any dynamic, global, or static allocations that was so I could avoid talking about lifetimes.

Quote:a pointer contains a memory location just like you said, however they are not identical to variable values.

How would you suggest pointers are not identical to variables?

Under the hood that is exactly what they are (usually equal to an int or long on most setups depending a on architecture word size and compiler defined size of the types). Though you're supposed to use them to store memory address you don't actually have to, you can replace your ints/longs(again, arch dependent) with a char* and have it work. Everything you can do with a variable you can do with a pointer, the only special thing is that the language supports dereferencing pointer types.
For me I've always regretting not learning about pointers and references till later in my programming career. Great article and hopefully it keeps someone from making the same mistakes I've made. I've written so many PHP lines like this

Code:
$a = 'value';
$a = modify_var($a);

When it could just pas by reference.

Code:
modify_var(&$a);

And of course pointers in C are a must.
(11-30-2015, 09:26 PM)dropzone Wrote: [ -> ]
Quote:I ctrl-F'd scope and didn't see you talk about that so I'd think that'd be rather important.

I avoided that intentionally, you might noticed I never used any dynamic, global, or static allocations that was so I could avoid talking about lifetimes.

Quote:a pointer contains a memory location just like you said, however they are not identical to variable values.

How would you suggest pointers are not identical to variables?

Under the hood that is exactly what they are (usually equal to an int or long on most setups depending a on architecture word size and compiler defined size of the types). Though you're supposed to use them to store memory address you don't actually have to, you can replace your ints/longs(again, arch dependent) with a char* and have it work. [b]Everything you can do with a variable you can do with a pointer, the only special thing is that the language supports dereferencing pointer types.[/b]

And subsequently indexing as well, since the [] operator is syntactic sugar for *(pointer + offset) in most cases, if not the reverse.
Code:
#include <stdio.h>

int main(void)
{
  int d[] = { 1, 2, 3, 4, 5 };
  int *p = &d[2];
  printf("%d\n", *p);
  printf("%d\n", p[-1]); /* *(p + -1) */
  printf("%d\n", -1[p]); /* -(*(1 + p)) (same as -p[1], not p[-1] because of operator precedence) */
  return 0;
}
If you want to learn C++ the perfect site is the official:
http://www.cplusplus.com/doc/tutorial/

This tutorial is ok too, but I don't see why would someone spend time writing a tutorial when it's already there in an easy to understand form.
(05-17-2016, 01:10 PM)charge Wrote: [ -> ]If you want to learn C++ the perfect site is the official:
http://www.cplusplus.com/doc/tutorial/

This tutorial is ok too, but I don't see why would someone spend time writing a tutorial when it's already there in an easy to understand form.

There is no official website for C++ and the default code highlighting theme is aesthetically pleasing. 

This is a good tutorial for beginners because it breaks the concepts down into digestible parts i.e. "A pointer points to data. Pointers can point to other pointers. The actual pointer is a memory location." Props to dropzone for writing so concisely. 

I'd like to suggest further reading with a guide written by prof Nick Parlente on pointers. It goes into detail on memory allocation and best practices for using pointers.