• Advertisement
Sign in to follow this  

Pointers. Why?

This topic is 2994 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay, I've been working through a C++ book for a while now and things have been going swimmingly, with me picking up each concept with great ease and retention. Then I got to pointers.I just don't get it. I can understand the syntax and the whole address-not-a-value thing about them, but I just can't retain them because I cannot see any practical application of them. Where and when would you use pointers in game development? I suppose that this may be my books fault because it teaches pointers by making you rewrite a program you already wrote using arrays by using vectors and iterators and stuff instead, and it all seems pointless (no pun intended) to me. Could you give some kind of practical example of where pointers would be used in game development(or any development for that matter)? I'm sorry if I sound ignorant and dumb, but I'm having serious trouble with this concept and really need help making it click. EDIT: Fixed a typo in the title

Share this post


Link to post
Share on other sites
Advertisement
The simplest reason is, you only have ~2MB of stack memory. If you need to use more than 2MB of memory, you need to allocate it with malloc/new (from which you get a pointer to retain the location of that object).

Another reason: you need an object to survive between different scopes or function calls, so allocate with malloc/new and pass it around via pointer.

In C++ you can also use polymorphism by retaining pointers to base class objects in a common list. Like all your game objects in a single list.

Dynamic memory data structures: linked list, binary tree, etc

Suffice it to say, they are vital. Right now they probably seem useless, but keep up your learning and their importance will become clear. By necessity, you have to introduce pointers before you introduce anything that uses pointers [smile]

-me

Share this post


Link to post
Share on other sites
imagine you have a game where the player has to carry 30 rocks from one side of the room to another (crappy game i know hehe).

so, your game has the following objects

PlayerObject -> 1 of these
RockObject -> 30 of these

when the player is moving a rock, you have to know which rock the player is moving. How do you do this? You have a pointer that points to which rock is being manipulated.

This lets you do this...

//make sure the rock moves as the player moves
PlayerObject.RockBeingCarried->Position = PlayerObject.Position

and if you want the player to move a different rock, you just set PlayerObject.RockBeingCarried to point to the new rock you want the player to be carrying.

hope that helps! (:

Share this post


Link to post
Share on other sites
Pointers encapsulate memory addresses. They allow you to operate on raw memory blocks, and to pass handles to such blocks around. It's a low level construct that is more convenient to use than assembly in low-level code that requires raw memory access.

C was originally designed to build the UNIX operating system, and C++'s backwards-compatibility to C includes pointers.

Share this post


Link to post
Share on other sites
Pointers are a means of providing reference semantics (I mean "reference" in the general sense, because C++ also has a concept of 'references' that mean something specific to C++, but also provide reference semantics).

They allow you to refer to something without actually having that something. A typical real world example is that of a house. If I want to show you my house, I give you my address (which can be viewed as a reference to my house). I don't build you a new copy of my house... that would be foolish.

There are many advantages to referential semantics, both from a performance perspective and a logical one. A reference of some sort to an object is often much smaller than the object itself, so passing it around is usually faster (the object itself is not copied, just the reference to that object). Additionally, without referential semantics, you wouldn't be able to write generalized functions such as apply_damage(Actor* actor) (which applies some damage to any arbitrary actor).

Note that we could also write apply_damage(Actor& actor) to use C++ references instead of pointers, and this would probably actually be preferable since references cannot be null, legally.

They are also how C++ allows you to get a reference to objects allocated at runtime (on the heap, via new).

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
The simplest reason is, you only have ~2MB of stack memory. If you need to use more than 2MB of memory, you need to allocate it with malloc/new (from which you get a pointer to retain the location of that object).

Another reason: you need an object to survive between different scopes or function calls, so allocate with malloc/new and pass it around via pointer.

In C++ you can also use polymorphism by retaining pointers to base class objects in a common list. Like all your game objects in a single list.

Dynamic memory data structures: linked list, binary tree, etc

Suffice it to say, they are vital. Right now they probably seem useless, but keep up your learning and their importance will become clear. By necessity, you have to introduce pointers before you introduce anything that uses pointers [smile]

-me


malloc? new? stack memory? Jeez . . . I'm starting to think my book is explaining things out of order, I've never heard any of those terms before. . . cripes.

Share this post


Link to post
Share on other sites
Here's a simple example, albeit one that is more for educational purposes than actual real use;

Say you're making a platformer game, where the player can run and jump. Let's assume you have a game controller with a DPad and A and B buttons, and you game code has a classes for Joystick, Button and Player to control them, something like this:


class Joystick {
public:
Button B;
Button A;
};

class player {
public:
Joystick joystick;
};

Joystick Joystick1;
Player Player1;






Imagine that these class do everything you'd expect them to do, there's obviously a bunch of code required, but this just imagine it all works for the sake of this example.

You might have some code like this:


void CheckForPlayerJump() {
if( Player1.joystick.B.isPressed() ) {
Player1.Jump();
}
}






This says, if player 1's joystick tells me they pressed the b button, make the player jump.

Simple right? Well what if the player changes the settings so that you the A button is the jump button? How would you do that? Here's how you could without pointers:


//Player uses the options screen to map the jump button to A which
//sets JumpButtonIsB to true
void CheckForPlayerJump() {
if( JumpButtonIsB ) {
if( Player1.joystick.B.isPressed() ) {
Player1.Jump();
}
} else {
if( Player1.joystick.A.isPressed() ) {
Player1.Jump();
}
}
}







Notice that we have the exact same code for A or B, with the exception of which button does the action. Now, here's how you might do that same thing with pointers:


Button *Player1Jump = &Joystick1.B;

void CheckForPlayerJump() {
if( Player1Jump->isPressed() ) {
Player1.Jump();
}
}






See how the jump-checking function doesn't have to know what button is used for jumping? All it knows is that some button is used, it doesn't care which one. Ever played a game where you could assign any key to any action? What if instead of a controller, you had a Keyboard class? Without pointers you might have something like this:


void CheckForPlayerJump() {
if( JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player1.Jump();
}
} if( JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player1.Jump();
}
} if( JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player1.Jump();
}
}
...//'til we get all the letters
}






So you'd have to check every single key this way. Now you might say "Couldn't I just put all the keys in an array and have an int to tell me which to use?" You sure could, but what if the objects were not in an array? What if a variable is given to you from a function? What if you don't know exactly what button is pressed? here's how you might do that with pointers:


KeyboardKey *Player1Jump = &Keyboard.Q;//or whatever the user picks

void CheckForPlayerJump() {
if( Player1Jump->isPressed() ) {
Player1.Jump();
}
}







Simpler, no? Now imagine we have two Players who can set their button preferences however they like, which of these is better:

No pointer:

void CheckForPlayerJump() {
if( Player1_JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player1.Jump();
}
} if( Player1_JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player1.Jump();
}
} if( Player1_JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player1.Jump();
}
}
...//'til we get all the letters for Player 1

if( Player2_JumpButtonIsQ ) {
if( Keyboard.Q.isPressed() ) {
Player2.Jump();
}
} if( Player2_JumpButtonIsW ) {
if( Keyboard.W.isPressed() ) {
Player2.Jump();
}
} if( Player2_JumpButtonIsE ) {
if( Keyboard.E.isPressed() ) {
Player2.Jump();
}
}
...//'til we get all the letters for Player 2
}






Or with pointers:

void CheckForPlayerJump( Player *p ) {
if( p.joystick.JumpButton->isPressed() ) {
p.Jump();
}
}

CheckForPlayerJump( Player1 );
CheckForPlayerJump( Player2 );






Much simpler. Also note, how the CheckForPlayerJump doesn't even know wick player it is using, it can work for any player.

One of the benefits of pointer is flexibility. You don't need to know exactly which object you are dealing with, you just need to know what type it is. When you are first starting out, that might not seem like a big deal, because all the programs in your book only have 2 or 3 objects. But when you are dealing with a game that has dozens, hundreds or thousands of objects, most of which are probably created on the fly, it's all but impossible not to use pointers.

Basically, one use of pointers in games is to deal with similar things in the same way, without having to hard code each one. Look up "Abstraction" on Google or Wikipedia to see why this is a good thing.

Another reason is that, when passing an object into a function, the entire object is copied to a local variable within that function. Passing a pointer to an object into a function just references the original object, without copying it. This means two things;
1) No needless copying, which can take a while depending on how bit the object is and,
2) You can modify the original object in the function


Your book had you use vectors and pointer instead of arrays, which isn't that big of a difference so you're right about that case being a bit unnecessary. But image if there was no array, that all those objects were created at run-time and just put into the vector.

[Edited by - NinjaMonkeyPirate on December 7, 2009 5:42:41 PM]

Share this post


Link to post
Share on other sites
You've covered references by now, surely? (Meaning specifically C++ ones with the "&")

At your stage, think of a pointer as being very similar to a reference as its used in similar circumstances. A few key differences are, with a pointer you can:

1) Increment it to point to the next type along in an array
2) Pass NULL to function expecting a pointer to indicate some optional behaviour that the function can pick up on given the NULL. Maybe the function would use the block of memory passed by a pointer, or if it's NULL then it would allocate a new block of its own or summat.

Both of these things can lead to bugs very easily, so use with care. Pointers do stuff that references can't, but the price is danger. (For example, maybe you shouldn't be allowed to increment it as in example 1), but theres nowt to stop you).

There are other uses, but those two should be enough for now. As others have said, you'll see why these things are as vital as int variables when you get a bit more general understanding.

Share this post


Link to post
Share on other sites
Quote:
Original post by NinjaMonkeyPirate
Here's a simple example, albeit one that is more for educational purposes than actual real use;

***truncated***



Wow . . . that. . . actually helped alot. Thank you. I think I really get it now.

And to Rubicon, no I haven't done references yet. The book I'm using seems to jump around alot, introducing things without explaining them and waiting until later parts of the book to explain what the heck was going on. Hence my frustration and confusion.

But yeah, thanks NMP, that seriously cleared this up for me.

EDIT: realized quoting the whole post was ugly, so I removed most of it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bromordra
malloc? new? stack memory? Jeez . . . I'm starting to think my book is explaining things out of order

May I ask what the book is called?

Share this post


Link to post
Share on other sites
One thing that I wish someone told me when I was learning C++ is... Don't use pointers unless you really need to.

Share this post


Link to post
Share on other sites
Quote:
Original post by c_olin
One thing that I wish someone told me when I was learning C++ is... Don't use pointers unless you really need to.


Eh, I'd say it's more accurate to say to use pointers when it calls for it.

How widely you use them more so depends on the complexity of what you're developing. They can take a bit to wrap your head around, but they're an incredibly useful concept to understand, and can save or cause you a lot of headaches.

My advice for the op is to write your own linked list; just a simple one, should do it. Also, a lot of the people who've posted above posted great explanations (which I wish I had when I was still in college).

Don't worry about it, even if you don't get it now, you'll get it eventually; as in all likelihood they'll be slowly drilled into your head over time.

EDIT: Wow... you know you're tired when your grammar becomes THIS bad...

Share this post


Link to post
Share on other sites
Quote:
Original post by c_olin
One thing that I wish someone told me when I was learning C++ is... Don't use pointers unless you really need to.
The corollary to that is that if you fully understand pointers, you will use them everywhere.

In addition, std::string, std::vector and std::list (as well as any other std:: construct) use pointers internally, so you while you may be able to avoid using pointers directly, and thus avoid understanding them, you are always using pointers...

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Quote:
Original post by c_olin
One thing that I wish someone told me when I was learning C++ is... Don't use pointers unless you really need to.
The corollary to that is that if you fully understand pointers, you will use them everywhere.

In addition, std::string, std::vector and std::list (as well as any other std:: construct) use pointers internally, so you while you may be able to avoid using pointers directly, and thus avoid understanding them, you are always using pointers...


You've completely missed the point of the advice given "Don't use pointers unless you really need to" is a paraphrase of "Don't handle memory directly in your program unless you really need to";

Anyone who truly understands pointers understands the resulting costly fallout of a mishandled pointer; The easiest way to avoid this is to minimise their use - preferably localised to as small a unit as possible.

in using STL containers, iterators, smart pointers, etc, memory is handled for you; not only this but those libraries are written by some of the best programmers in the world - if you understand how these libraries work, chances are the code you'll write with, say, a std::list or std::deque will be more efficient than something you've written yourself, not to mention safer and more readable.

Share this post


Link to post
Share on other sites
I take "Don't use pointers unless you really need to" to mean, "use references instead if possible" ;D

But yes, pointers are dangerous so it's best to wrap their usage up in a tried-and-tested class (e.g. STL containers) and then use it instead ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by c_olin
One thing that I wish someone told me when I was learning C++ is... Don't use pointers unless you really need to.


I would say that if you want to stay away from pointers, then you must stay away from C++ in the first place :-)

To the OP: don't worry if something seems unclear at first. Books organize informations as the autors finid it best, but that dosn't necessarily match your own way to learn. I've read "Physically based Rendering" and it is one of the best books I've ever read, yet there is no way you can get it at the first read, as every chapter is bound with every other, without following an incremental path :-)

I find it natural to first teach pointers and then dinamic allocation. I recall the first time I encountered pointer was with the (C, not C++) scanf() function to read characters from the standard input, and the book did not even said that I was using pointers!

Share this post


Link to post
Share on other sites
Quote:
Original post by Bench
You've completely missed the point of the advice given "Don't use pointers unless you really need to" is a paraphrase of "Don't handle memory directly in your program unless you really need to";

Anyone who truly understands pointers understands the resulting costly fallout of a mishandled pointer; The easiest way to avoid this is to minimise their use - preferably localised to as small a unit as possible.
I am going to respectfully disagree. Pointers are not inherently problematic - the problem is programmers who assign stupid values to those pointers.

As long as you use pointers in reasonable cases (i.e. as references and as iterators), all is well. Pointers become problematic when someone decides to use null pointers (without the matching checks), decides to improperly cast types, or otherwise assigns garbage values to them.

And these problems aren't unique to pointers, they are endemic in these usages. Assign a garbage value to an iterator, and your program crashes just as hard, same goes for an integer index into an array. Cast a reference to a non-matching type, and everything goes to hell just the same as with the pointer. Manage to create a null reference...

Is it easier to create a garbage pointer? Sure, the language doesn't try to protect you in this area. But the point is that you can break any language construct through misuse, and the whole 'fear of pointers' thing only prevents people from becoming proficient enough with them to avoid problems.

Share this post


Link to post
Share on other sites
I'll try to give an easy to understand example. They are probably introduced in the book before you've had time to know enough of the language, and work through complex enough example programs to see why they are useful.

A pointer is useful when you want to point to an address of something that may already exist.

Say you have game objects. They reference a 3D model, and that model references a texture.

You could specify that all game objects load their own model and textures, but this could be very wasteful, as you are going to load the same data more than once and just store redundant copies of them.

Instead, you can have your game objects store pointers to models and textures, and let an asset manager take care of loading them. No matter what happens, the asset manager will return a valid pointer to a texture.

The Texture manager will check through it's array/list of already loaded textures, and if it finds the one requested, will return the pointer. If not, it will allocate a new texture and return the new pointer. It can also return the default texture should there be no memory left, or 0 for null.

Or...

Think of a graphics card. It has a front buffer that is sent to the monitor every frame to draw the picture you see on your screen. A program will also allocate a backbuffer as a temporary drawing space and flip the buffers when drawing is done.

What is a more efficient way to do this?

1) Copy all of the contents of the back buffer memory onto the memory area occupied by the front buffer

or

2) Simply swap 2 pointers, having the back buffer become the front buffer, and vice-versa?

Share this post


Link to post
Share on other sites
I'll just reiterate my latest reply on this subject:
yES search the forums this has been covered numerous times. To quicky summarize if you are still fuzzy on them as you seem to be you don't need them. Practice learning to write programs first and when you start to write games that use C++ and DirectX using pointers then ask this question again if you still having problems.
Remember millions of programmers, I'm thinking VB6, got by for many years without having to deal with pointers. Hence, one of the reasons they were probably looked down upon by other programmers. See #3 below.
If you read the new Stroustroup Swan book he doesn't even cover pointers until PartIII and even then only because of the following reasons:
#1you would be unable to implement a new container (should you need one, and that's not uncommon).
#2 You would be unable to read huge amounts of C and C++ code that directly uses memory.
#3 More philosophically, I am among the large group of computer professionals
who are of the opinion that if you lack a basic and practical understanding of
how a program maps onto a computer's memory and operations, you will have
problems getting a solid grasp of higher-level topics, such as data structures , algorithms,and operating systems

Sounds like you are getting the programmer humor pretty well though LOL:
"...it all seems pointless (no pun intended)..."

Share this post


Link to post
Share on other sites
Quote:
Original post by daviangel
Remember millions of programmers, I'm thinking VB6, got by for many years without having to deal with pointers. Hence, one of the reasons they were probably looked down upon by other programmers.


The irony there is that VB6 was programmed in C++ and that code uses numerous pointers, just like most software does :P

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement