Jump to content
  • Advertisement
Sign in to follow this  
Steve25

Pointers

This topic is 2986 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

I realise this is probably going to seem like a very newbie question but I can't seem to get my head around Pointers in C++.

I'm mostly a C# and Java programmer and mostly to create games I've been using the XNA Framework with the C# Programming language. I've only really done simple 2D games as of yet but they're still great fun to make and play. However I've realised that if I want to be serious about Games development C++ is the way to go.

I've done a lot of C++ in the past but lately I've been trying to learn Pointers. I can create Pointers and make them work etc. but to be honest I don't really see the point in Pointers. The only Pointers I've ever really found use for is the this keyword and passing data by reference in methods.

So could anyone perhaps try to explain to me when you would use Pointers, why you would use them instead of ordinary variables and how they are useful in games and other software. Thanks

Share this post


Link to post
Share on other sites
Advertisement
For example you have one huge 3D Model which takes 100 MB RAMs. Without pointers your computer will copy it to use in some function, that function will copy it again to use in another function, and it'll keep going, even if either of functions edit Model, first Model you had won't change.. Pointers allow to read and modify original Model, without copying it.

Share this post


Link to post
Share on other sites
Pointers have a couple of uses:

1) Avoid copies.

When you pass or return a complex type to a function, you can pass it by value or by reference. By value will create a copy, which is often unnecessary. You can use a pointer to pass it by reference, but in C++ you would use a C++ reference, like so:

void foo(const ComplexType &instance)
{
// Look ma, no copies!
}



You might need to use pointers for this when passing to external code, as mentioned in #4

2) Optional Aguments

If you want to have an optional argument, you could use a pointer. Then you can either pass NULL, the address of a local variable or the value of a heap pointer. In modern C++, you could use boost::optional<> for this. You might need to use pointers for this when passing to external code, as mentioned in #4

3) Implementing new data structures

If you need to implement a new data structure (check that it isn't already available in the standard library first!) then you will often find yourself using raw pointers.

4) Large arrays

The stack is limited. On Windows, you have about 1MB of stack, and you will want to save most of that for function calls. So if you have any large pieces of data, you have to dynamically allocate it, and that involves pointers if done manually. However, modern C++ users would use std::vector<> instead of managing raw arrays.

5) Legacy Code / Interfacing with an API

There is lots of pre-existing code out there that uses pointers. As such, you have no choice but to use the existing functions. A very frequent example is C strings, or null terminated character arrays. Most low level APIs will require you to pass C strings as a pointer.

APIs are often written in C, and will expose all complex types via pointers. These can be wrapped with RAII classes to make them safer to use, but you still need to deal with pointers when wrapping them.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ripiz
For example you have one huge 3D Model which takes 100 MB RAMs. Without pointers your computer will copy it to use in some function, that function will copy it again to use in another function, and it'll keep going, even if either of functions edit Model, first Model you had won't change.. Pointers allow to read and modify original Model, without copying it.


If you pass data to a function by value yes it makes a copy but that copy is erased when the method expires so it's not really a problem. For that reason I don't really see how Pointers would be beneficial here.

rip-off: Number 1 I see the use for, but of course you're using a reference there which I guess is a type of pointer. However, for point number 2 I guess you could do it that way but isn't that what method overloading is for? Number 3, isn't that very unlikely unless of course you mean creating your own types via classes? Not really come across the one for number 4 but I guess that's similar to using Lists in C#. And number 5 is the only time I've really used them because I've had to.

Share this post


Link to post
Share on other sites
Quote:
If you pass data to a function by value yes it makes a copy but that copy is erased when the method expires so it's not really a problem.
Wait, what? 1) Time is required to make that copy and 2) You need memory for that unnecessary duplicate

That's not a problem at all? That's an enormous performance penalty.

Want to understand why pointers exist? Create a linked list. Once you have done that, you'll get it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Steve25
If you pass data to a function by value yes it makes a copy but that copy is erased when the method expires so it's not really a problem. For that reason I don't really see how Pointers would be beneficial here.


Lets say your Model is 100 MB in size


vector<Player> players;
Model model("my 100 mb model.x");
for(int i = 0; i < 10; i++){
players.push_back(Player(i * 32, i * 32, model)); //you just took 100 mb, and again, and again, and again...
}
//looks like 1 gb RAMs gone
//also spent like 10 seconds copying data

//Instead you could have done
vector<Player> players;
Model *model = new Model("my 100 mb model.x");
for(int i = 0; i < 10; i++){
players.push_back(Player(i * 32, i * 32, model));
}
//only 100mb + 10*4 bytes for pointers, and like 0.000001 second to set those pointers




Quote:
Original post by Steve25
number 2 I guess you could do it that way but isn't that what method overloading is for?

Without pointers one method will be able to return 1 value, with pointers you can modify as many values as you wish

Quote:
Original post by Steve25
Number 3, isn't that very unlikely unless of course you mean creating your own types via classes?

I'm really sorry for you if you won't use classes or structures in your code

Share this post


Link to post
Share on other sites
Quote:
Original post by Steve25
If you pass data to a function by value yes it makes a copy but that copy is erased when the method expires so it's not really a problem. For that reason I don't really see how Pointers would be beneficial here.

They give you the option of avoiding the performance hit. As a C#/Java programmer, you know that objects are passed by reference in these language. This is similar to passing a pointer in C++. Passing a value in C++ is like a struct in C#, or using a deep clone() method for class types in Java/C#. You can see that this is unnecessary in many cases.

There are also uncopyable classes to consider. Types that represent external entities are frequently noncopyable. So you can't copy standard file types, most libraries won't let you copy a socket and you often won't find a copyable texture type. To pass these to functions, you must use a reference or a pointer.
Quote:

Number 1 I see the use for, but of course you're using a reference there which I guess is a type of pointer.

It is best if you try separate the ideas of pointers and C++ references. Semantically, a C++ reference is well defined (it is not-null, not-reseatable and not an array). A C++ pointer could be NULL, could point to an arbitrary element of an array, or could be uninitialised if you aren't careful.
Quote:

However, for point number 2 I guess you could do it that way but isn't that what method overloading is for?

Yes. But consider the case where the method body is complex. You don't want to have two versions of non-trivial code. Instead you write the same function, and just add null checks before using the optional parameter. Or consider providing an optional parameter to "write-back" through. An example:

/*
Returns true if the two lines intersect.
Writes the intersection point to "out" if out is not null.
*/

bool intersection(const Line &one, const Line &two, Point *out)
{
// ...
}

// Convenience function for when the intersection point is not needed
bool intersection(const Line &one, const Line &two)
{
return intersection(one, two, NULL);
}



Note how we only had to write the logic once, which is what you should strive for.
Quote:

Number 3, isn't that very unlikely unless of course you mean creating your own types via classes?

It isn't common, but the C++ standard library does not contain implementations of lots of the spatial partioning structures you are likely to need as a game programmer. Either you, or the person who writes the library you choose to use, will need pointers for this.
Quote:

Not really come across the one for number 4 but I guess that's similar to using Lists in C#.

Exactly. In C++ you would generally use std::vector<> where C# uses List. But std::vector<> must use pointers, as this is the only way to handle dynamic allocation in C++.
Quote:

And number 5 is the only time I've really used them because I've had to.

This isn't likely to change. Library writers generally aim for C or simple C++. This simplifies things like building the library as a DLL. This leaky abstraction is then pushed onto you in the difficulty in interfacing with the library.

Also, library writes hate additional dependencies. You won't see too many libraries using boost, many will even avoid the standard library in case you aren't using it yourself. This might just be the fact that I've mainly used game libraries, which tend to be extreme about this sort of things. Even in the standard library the file interface uses C strings, to avoid the dependency on std::string!

Share this post


Link to post
Share on other sites
One thing I don't think has been pointed out is that the OP is used to Java and C#. So all of the arguments about by-value versus by-ref are actually off the mark. The OP is used to using pointers each and every day of his programming life, he just didn't realized it. Reference in Java and C# ARE POINTERS, plain and simple. The only difference is the language has limited what you are allowed to do with them and made the syntax the same as when you are not using pointers.

In the original C-like language there are 2 types of variables, variables that ARE the address of a value and variables that are a value which is the address of another value. The first are things like int and char. When you declare "int a;" the compiler sets aside space for an int (4 bytes usually) and each place in the program where it needs to use a it compiles in the address it has set aside. When you declare "int *b;" the compiler creates space for a pointer (also often 4 bytes) and each time you refer to "b" the compiler compiles in the address it has set aside for this pointer. But with pointers you can set the pointer's value equal to the address of other values, so you can write code which works on different values, without realizing it. For instance if you set aside 100 ints in a row like "int c[100];", then you can do things like "a = &c[10]" to say "set a to the address of element 11 in the array" ... which you could then set, modify, compare or whatever. Perhaps you are looping through the array sorting it.

Or imagine a game with the player and a list of 100 monsters. you might find it useful to have a monster pointer to store the player's current target ... which would be a pointer to 1 of the 100 monsters within the list of monsters. Etc.

Now everything I've said makes sense to you and seems silly, because you already use pointers all the time, you just call them "references". A reference is a pointer. In fact before C++ added the special "reference" syntax, everyone who wrote in C and C++ used the term reference to mean pointer. passing a pointer was called "pass by reference". Then people like C++, Java and other languages decided they wanted to make it easier for the compiler to keep programmers from doing risky and sometimes incorrect things with pointers, so they can up with a new type of variable, a limited pointer, and they called it a reference. When ALL of these languages first implemented these references, it was exactly the same opcodes that they used for pointers ... the only difference was that they did more compile time checking to make sure the programmer was using them according to the limited contract they agreed to, and they didn't provide any means for the programmer to get the actual numeric address of the pointer ... therefore the programmer couldn't do things like add 2 references together to get some random third address and then try to use that address as if it made sense.

In C# when you write:


// this C#
Control b = new Button();
b.Text = "Push Me";

// is the same as THIS C++
Control *b = new Button();
b->Text = "Push Me";

// and is NOT the same as this C++ (which makes no sense)
Control b = new Button();
b.Text = "Push Me";


So when you write Java and C# using classes, you are using pointers, so when you ask "WHY would anyone use pointers", you are asking the wrong question. You really mean something more like "Why or when should I use C++ pointers instead of C++ references".

To which there are many valid answers ... and the short answer is, in C++ you would use reference ANY AND EVERYWHERE you possibly can ... but there are many many places that references in C++ cannot suffice (because the reference in C++ is actually less powerful than a reference in Java or C# ...).

Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
In C# when you write:


// this C#
Control b = new Button();
b.Text = "Push Me";

// is the same as THIS C++
Control *b = new Button();
b->Text = "Push Me";

// and is NOT the same as this C++ (which makes no sense)
Control b = new Button();
b.Text = "Push Me";



Actually, that's not entirely correct. The equivalent C++ version would use references:

Control& b = Control();
b.Text = "Push me";


C# references are not equivalent to C++ pointers. C# distinguishes between references and pointers just like C++ does.

The main difference between C# refs and C++ refs is that C# classes use reference semantics by default, whereas C++ classes use value semantics by default (structs use value semantics in both). C# pointers are a slightly more limited version of C++ pointers.

[Edited by - Fiddler on July 17, 2010 7:07:25 PM]

Share this post


Link to post
Share on other sites
Thanks for all of your replies I appreciate the help.

I see now that where I've been writing software in C# and Java I have been using Pointers, but not realised it. It's been there working behind the scenes so the developers of that language don't need to worry about it. The ref keyword in C# is basically a form of reference but in a much simpler form.

Before I thought you should only use Pointers where you really have to, where normal variables just wouldn't work but from reading your comments that doesn't appear to be the case.

Ripiz: Not sure I understand, you're using the same model variable not ten different ones?

rip-off: The optional argument in a method that you explained makes sense to me now thank you. Most C++ primers will explain to use methods will standard variables in its parameters but do you think you should always use references?

Xai: If you are only holding that one control then why do you have to use a Pointer?

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!