5

I am learning C++ from a game development standpoint coming from long time development in C# not related to gaming, but am having a fairly difficult time grasping the concept/use of pointers and de-referencing. I have read the two chapters in my current classes textbook literally 3 times and even googled some different pages relating to them, but it doesn't seem to be coming together all that well.

I think I get this part:

#include <iostream>

int main()
{
    int myValue   = 5;
    int* myPointer = nullptr;

    std::cout << "My value: " << myValue << std::endl; // Returns value of 5.
    std::cout << "My Pointer: " << &myValue << std::endl; // Returns some hex address.

    myPointer  = &myValue; // This would set it to the address of memory.
    *myPointer = 10; // Essentially sets myValue to 10.

    std::cout << "My value: " << myValue << std::endl; // Returns value of 10.
    std::cout << "My Pointer: " << &myValue << std::endl; // Returns same hex address.
}

I think what I'm not getting is, why? Why not just say myValue = 5, then myValue = 10? What is the purpose in going through the added layer for another variable or pointer? Any helpful input, real life uses or links to some reading that would help make sense of this would be GREATLY appreciated!

Dan Watkins
  • 918
  • 9
  • 25
Volearix
  • 1,573
  • 3
  • 23
  • 49
  • 3
    In the very narrow case of the code you have posted, it serves no purpose; but the example is trying to explain to you how it works, not how you can use it to do interesting stuff. Try adding another function and play with the code to try to figure out what you can do. – vanza Dec 16 '13 at 19:14

11 Answers11

15

The purpose of pointers is something you will not fully realize until you actually need them for the first time. The example you provide is a situation where pointers are not needed, but can be used. It is really just to show how they work. A pointer is a way to remember where memory is without having to copy around everything it points to. Read this tutorial because it may give you a different view than the class book does:

http://www.cplusplus.com/doc/tutorial/pointers/

Example: If you have an array of game entities defined like this:

std::vector<Entity*> entities;

And you have a Camera class that can "track" a particular Entity:

class Camera
{
private:
   Entity *mTarget;  //Entity to track

public:
   void setTarget(Entity *target) { mTarget = target; }
}

In this case, the only way for a Camera to refer to an Entity is by the use of pointers.

entities.push_back(new Entity());
Camera camera;
camera.setTarget(entities.front());

Now whenever the position of the Entity changes in your game world, the Camera will automatically have access to the latest position when it renders to the screen. If you had instead not used a pointer to the Entity and passed a copy, you would have an outdated position to render the Camera.

Dan Watkins
  • 918
  • 9
  • 25
  • 1
    +1 The only answer so far showing a case where references would not work (that's because you provide a setter which needs to reseat the pointer, which is not possible with references). I also like that your example has to do with game development. :) – leemes Dec 16 '13 at 19:25
  • This is a good example because it's aimed at OP's goal as well – Natan Streppel Dec 16 '13 at 19:26
  • 1
    Although it might be better to have the vector containing values and only use pointers where you refer to objects you don't own (i.e. your Camera class) – leemes Dec 16 '13 at 19:27
  • @Dan Watkins I have a bad feeling your line The purpose of pointers is something you will not fully realize until you actually need them for the first time. is going to sum up this question for the most part for me. Perhaps I need to just keep reading on past this chapter and hope it makes sense to me as I go? – Volearix Dec 16 '13 at 19:29
  • 1
    @Volearix Keep in mind that in languages such as C# and Java all object variables are pointers, i.e. such languages use *pointer semantics*, but C++ has *value semantics*. This means that all non-pointer variables in C++ are *instances* themselves, assigning it to somewhere else / passing it to a function will copy the instance, not refer to the instance. That's the main idea you should understand. – leemes Dec 16 '13 at 19:31
  • @DanWatkins It's just a bad feeling considering I tried this course once before a few years back and decided to put it off because it didn't make sense to me (I defaulted back to visual basic then c#). This time around I jumped ahead in my book and download examples to look at the final game code you end up with and it's VERY apparent that pointers are a necessity to understand. My brain wheel just isn't turning on these things! I can make some code that uses them already; maybe it just needs to sink in while I push forward with the class. – Volearix Dec 16 '13 at 19:37
  • @leemes So if a pointer is is passed to a function, are you saying it would be the same memory address? (Sorry if I just butchered what you said! >.< ) – Volearix Dec 16 '13 at 19:38
  • 1
    Passing a pointer or reference in C++ to a function will behave similar to pass an object variable to a function in C# (i.e. changes made inside the function reflect on the object you passed in, not on a copy). When passing the object *by value* in C++, it will be copied and such changes aren't visible outside. – leemes Dec 16 '13 at 19:41
  • OH! So just like in c# when using private void Export(DataTable dt) opposed to private void Export(ref DataTable dt) – Volearix Dec 16 '13 at 19:43
  • 2
    @DanWatkins: There is a subtle issue with this code, *stability*. When adding an element to a `vector`, it may relocate all previous elements it held to another memory location, invalidating all references/iterators previously created. And `Camera` will thus soon hang onto a **dangling pointer**. – Matthieu M. Dec 16 '13 at 19:44
  • 1
    @MatthieuM. That's right. At first I had the vector storing pointers, which I'll change it back to that. – Dan Watkins Dec 16 '13 at 19:48
  • 1
    Sorry guys this was my fault. Even better is storing `unique_ptr`s in the vector and use raw pointers in the Camera class. This indicates that the code where the vector lives *owns* the objects and the instances are cleaned up automatically. – leemes Dec 17 '13 at 17:08
  • It's fine. I should have reviewed the design better. I'll add something about smart pointers. – Dan Watkins Dec 19 '13 at 04:09
2

If you pass an int by value, you will not be able to change the callers value. But if you pass a pointer to the int, you can change it. This is how C changed parameters. C++ can pass values by reference so this is less useful.

f(int i)
{
  i= 10;
  std::cout << "f value: " << i << std::endl;
}
f2(int *pi)
{
    *pi = 10;
    std::cout << "f2 value: " << pi << std::endl;
}

main()
{
    i = 5
    f(i)
    std::cout << "main f value: " << i << std::endl;
    f2(&i)
    std::cout << "main f2 value: " << i << std::endl;
}

in main the first print should still be 5. The second one should be 10.

Robert Jacobs
  • 3,266
  • 1
  • 20
  • 30
2

TL;DR: pointers are useful when multiple places need access to the same information

In your example they aren't doing much, like you said it's just showing how they can be used. One thing pointers are used for is to connect nodes like in a tree. If you have a node structure like so...

struct myNode
{
    myNode *next;
    int someData;
};

You can create several nodes and link each one to the previous myNode's next member. You can do this without pointers, but the neat thing with pointers is because they are all linked together, when you pass around the myNode list you only need to pass the first (root) node.

The cool thing about pointers is that if two pointers are referencing the same memory address, any changes to the memory address are recognized by everything referencing that memory address. So if you did:

int a = 5; // set a to 5
int *b = &a; // tell b to point to a
int *c = b; // tell c to point to b (which points to a)

*b = 3; // set the value at 'a' to 3
cout << c << endl; // this would print '3' because c points to the same place as b

This has some practical uses. Consider you have a list of nodes linked together. The data in each node defines some sort of task that needs to be done that will be handled by some function. As new tasks are added to the list, they get appended to the end. Since the function has a pointer to the node list, as tasks are added on it receives those as well. On the other hand, the function can also remove tasks as it completes them, which are then reflected back across any other pointers that are looking at the node list.

Pointers are also used for dynamic memory. Say you want the user to enter in a series of numbers, and they tell you how many numbers they want to use. You could define an array of 100 elements to allow for up to 100 numbers, or you could use dynamic memory.

int count = 0;

cout << "How many numbers do you want?\n> ";
cin >> count;

// Create a dynamic array with size 'count'
int *myArray = new int[count];

for(int i = 0; i < count; i++)
{
    // Ask for numbers here
}

// Make sure to delete it afterwars
delete[] myArray;
Jessie
  • 2,319
  • 1
  • 17
  • 32
2

What is the purpose in going through the added layer for another variable or pointer?

There isn't one. It's a deliberately contrived example to show you how the mechanism works.

In reality, objects are often stored, or accessed from distant parts of your codebase, or allocated dynamically, or otherwise cannot be scope-bound. In any of these scenarios you may find yourself in need of indirectly referring to objects, and this is achieved using pointers and/or references (depending on your need).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

For example some objects have no name. It can be an allocated memory or an address returned from a function or it can be an iterator. In your simple example of course there is no need to declare the pointer. However in many cases as for example when you deal with C string functions you need to use pointers. A simple example

char s[] = "It is pointer?";

if ( char *p = std::strchr( s, '?' ) ) *p = '!';  
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Take the example where you have a pointer to a class.

struct A
{
    int thing;
    double other;
    A() {
        thing = 4;
        other = 7.2;
    }
};

Let's say we have a method which takes an 'A':

void otherMethod()
{
    int num = 12;
    A mine;
    doMethod(num, mine);
    std::cout << "doobie " << mine.thing;
}

void doMethod(int num, A foo)
{
    for(int i = 0; i < num; ++i)
        std::cout << "blargh " << foo.other;
    foo.thing--;
}

When the doMethod is called, the A object is passed by value. This means a NEW A object is created (as a copy). The foo.thing-- line won't modify the mine object at all as they're two separate objects.

What you need to do is to pass in a pointer to the original object. When you pass in a pointer, then the foo.thing-- will modify the original object instead of creating a copy of the old object into a new one.

leemes
  • 44,967
  • 21
  • 135
  • 183
Kieveli
  • 10,944
  • 6
  • 56
  • 81
1

We use pointers mainly when we need to allocate memory dynamically. For example,To implement some data structures like Linked lists,Trees etc.

Ravi
  • 41
  • 3
1

From C# point of view pointer is quite same as Object reference in C# - it is just an address in memory there actual data is stored, and by dereferencing it you can manipulate with this data.

First of non-pointer data like int in your example is allocated on the stack. This means that then it goes out of the scope it's used memory will be set free. On the other hand data allocated with operator new will be placed in heap (just like then you create any Object in C#) resulting that this data will not be set free that you loose it's pointer. So using data in heap memory makes you do one of the following:

  • use garbage collector to remove data later (as done in C#)
  • manually free memory then you don't need it anymore (in C++ way with operator delete).

Why is it needed? There are basically three use-cases:

  1. stack memory is fast but limited, so if you need to store big amount of data you have to use heap
  2. copying big data around is expensive. Then you pass simple value between functions on the stack it does copying. Then you pass pointer the only thing copied is just it's address (just like in C#).
  3. some objects in C++ might be non-copyable, like threads for example, due to their nature.
dant3
  • 966
  • 9
  • 26
  • 1
    Pointers (or references) are also used for polymorphism. A list of shape pointers can point to numerous different shapes, while a list of shape values can only point to the base shapes. – YoungJohn Dec 16 '13 at 23:11
1

Pointers (or references) are vital for the use of dynamic polymorphism in C++. They are how you use a class hierarchy.

Shape * myShape = new Circle();
myShape->Draw(); // this draws a circle
// in fact there is likely no implementation for Shape::Draw

Attempts to use a derived class through a value (instead of pointer or reference) to a base class will often result in slicing and losing the derived data portion of the object.

YoungJohn
  • 946
  • 12
  • 18
0

It makes a lot more sense when you're passing the pointer to a function, see this example:

void setNumber(int *number, int value) {
    *number = value;
}

int aNumber = 5;
setNumber(&aNumber, 10);
// aNumber is now 10

What we're doing here is setting the value of *number, this would not be possible without the use of pointers.

If you defined it like this instead:

void setNumber(int number, int value) {
    number = value;
}

int aNumber = 5;
setNumber(aNumber, 10);
// aNumber is still 5 since you're only copying its value

It also gives better performance and you're not wasting as much memory when you're passing a reference to a larger object (such as a class) to a function, instead of passing the whole object.

Johan Lindskogen
  • 1,246
  • 1
  • 8
  • 25
  • 1
    "this would not be possible without the use of pointers" => Wrong, you can use references, and I personally even find it better than using pointers for cases like this. – leemes Dec 16 '13 at 19:24
  • 1
    They are *kind of similar* but also very different. References are more like named aliases and more high level; pointers are memory addresses and more low level. References *always* refer to an existing object, can't be reseated, can't be used to iterate through a contiguous array of elements, can't be null, ... – leemes Dec 16 '13 at 19:28
  • 1
    ... do not imply memory ownership or responsibility, can refer to temporaries, ... There might be more differences than similarities. – MSalters Dec 17 '13 at 11:37
0

Well to use pointers in programming is a pretty concept. And for dynamically allocating the memory it is essentiall to use pointers to store the adress of the first location of the memory which we have reserved and same is the case for releasing the memory, we need pointers. It's true as some one said in above answer that u cannot understand the use of poinetrs until u need it. One example is that u can make a variable size array using pointers and dynamic memoru allocation. And one thing important is that using pointers we can change the actual value of the location becaues we are accessing the location indirectly. More ever, when we need to pass our value by refernce there are times when references do not work so we need pointers.

And the code u have written is using dereference operator. As i have said that we access the loaction of memory indirectly by using pointers so it changes the actuall value of the location like reference objects that is why it is printing 10.

Ali Raza
  • 191
  • 2
  • 12