Sign in to follow this  
Helo7777

A little explanation on pointers please..

Recommended Posts

Hi all I know its bit of a noobish question, and I have been programming in c++ for a while but...While looking through others code i notice that in their classes some members have pointers while others dont. Could someone please explain to me why some are created as pointers while others arnt? Why not just make all members pointers? thanks

Share this post


Link to post
Share on other sites
enum gender { Male, Female };
struct person
{
gender g;
};


This means that the person has a gender, which is the expected situation.


struct person
{
gender *g;
};


This means that the person may or may not have a gender (after all, a pointer can be null), which in itself is silly: how could a person not have a gender? Besides, even when a person does have a gender, it's actually someone else's gender and the person is merely making a reference to that gender without owning it. Even worse: we could have it reference another gender instead of the old one!

Share this post


Link to post
Share on other sites
Memory for non-pointer members is reserved at program start, whereas for pointers members, it's usually done when needed. So for members which need a lot of space, I guess it makes sense to store them as pointers and only create the actual instance when needed, but for small ones for which are are sure that you well need them anyway, you would want them not be a pointer because it frees you of having to memory-manage them (new/delete)

Share this post


Link to post
Share on other sites
Quote:
Original post by michaweyel
Memory for non-pointer members is reserved at program start, whereas for pointers members, it's usually done when needed.


How does the program know, when it's starting, how much memory will be required for the members of all instances that will exist? For instance, as pseudocode:

main:
ask user for integer i
repeat i times
create object of class X


In essence, C++ class member variables are inlined: they are part of the class' memory footprint. When you instantiate the class, the program allocated memory for it which is then used by all its inlined members.

Share this post


Link to post
Share on other sites
Quote:
Original post by michaweyel
Memory for non-pointer members is reserved at program start
No, it is reserved when the containing class is created.

Non-pointer members/objects are also called "auto" variables (members/objects,...) because memory is handled "automatically".

Auto variables are allocated when they get in scope, and deallocated when they leave scope. In the particular case of a class member, the scope is the lifetime of the object the member is in. It exists from just before the beginning of your constructor throughout the lifetime of your class until just after the end of your destructor. You don't need to do anything about it, and there is no possibility of a memory leak or an invalid pointer.
While it may seem that auto members are therefore the perfect solution and preferrable to pointers in every way, this is not always the case. Either solution has advantages and disadvantages.

Auto variables live on the stack. Pushing some data onto the stack is practically guaranteed to take no longer than maybe half a dozen cycles. On the other hand, freestore which is used for pointer members regularly takes several hundreds of cycles, and has no upper limit (might take dozens of milliseconds). Also, the processor's cache helps for frequently allocated/deallocated stack objects, which doesn't work so well for some objects scattered at more or less random locations.
On the other hand, stack size is limited (usually a megabyte or two), while freestore is not (well... it is of course limited by the total amount of virtual memory). Allocating an array of 1,000,000 objects on the stack will almost certainly be a problem, while it won't (usually) for freestore. Also, operator new has a well-defined behaviour for failure (throws std::bad_alloc), while a stack overflow will just crash and burn.
Assigning a pointer to another pointer copies an address. Assigning an auto object to another calls the copy constructor. This is less efficient, and also may not be what you want at all. Think of what happens if you put a std::auto_ptr into a container, for example.
Pointers allow you to declare a class that contains another class the compiler does not know anything about. This means you can use a class that is defined in a different header without having to include that header (saving compilation time) or a class that is only defined later in the same file (sometimes helps to break cyclic dependencies). It is enough to provide a forward declaration in this case. Auto variables cannot work like this, as the compiler does not know what to do.

Share this post


Link to post
Share on other sites
Pointer points to a memory address. It says something along the lines: value of variable can be found at this location in memory.

This can be used for several purposes.

- Sharing of data. Rather than e-malining you the contents of google, I e-mail you a "pointer", which is www.google.com. Now you, and anyone else who has the address can access the database. Even more, if the database changes, all those that have the pointer to it, always use the latest version. If everyone had all the contents, they would need to receive all the updates any time google updates their index.

- Dynamic binding. If something is declared as a pointer-to, the pointer can be re-targetted. A player-pointer may point to player A. But then, we switch targets, and same pointer now points to player B object.

- Direct memory access. Since pointer is an address, you can make it have any value, and effectively point at arbitrary location in RAM (almost). This allows you to modify working memory directly.

- Life cycle management. Sometimes, life cycle of auto objects isn't suitable, and you need to make an object outlive its scope. This is done through new or malloc, object is allocated on freestore, and returns a pointer.

- Pointer arithmetic. While less needed than in C, pointer arithmetic allows for a certain way of data manipulation which turns out to be quite convenient.

- Arrays. Pointers can represent arrays, or can be treated like arrays. Generally not recommended practice.

Share this post


Link to post
Share on other sites
At a low level, it's like Antheus says (although the "array" and "pointer arithmetic" ideas are strongly related, and I wouldn't really count them as separate points, although I would of course recommend things like std::vector for C++ code).

At a high level, it's the classic engineering trade-off of flexibility versus simplicity. You may have noticed that the human body contains different types of joints: most restricted to a single "axis" of motion (e.g. elbow), but some that are rotating ball joints that can turn about more or less any direction until you hit another bone (e.g. shoulder). You might think that we could all be master contortionists if we had a rotating ball joint for every joint. But actually, we would need a much more complicated (and probably stronger) system of muscles and tendons just to avoid being permanently collapsed into a heap on the floor.

In many cases, we can avoid the dangers of raw pointers by using "smart" pointers - actually instances of classes that behave like pointers. In C++, we can do this with operator overloading: it is possible to overload the unary operator* (dereference, not multiplication - that's binary operator*), and operator->. This is kind of like buying joints with tendons pre-attached in a specific way, to make it easier to assemble the whole thing.

Share this post


Link to post
Share on other sites
Don't be scared of pointers, they are an extremely powerful programming concept and while open to abuse games wouldn't ship without them. Period.

A pointer "points" at a section of memory. This section of memory may be a member of a struct somewhere, memory that was allocated to the pointer, or a block of memory returned by some function. Because the pointer doesn't "own" the memory explicitly it is possible for something else to delete it leaving the pointer "dangling", or pointing at now invalid memory (during most game development there are many bugs relating to this scenario!).

Pointers allow for a powerful C++ mechanism called "polymorphism". This is well worth your time researching.

Smart pointers can be very useful and can save you trouble in the longer run but often have side-effects that need debugging in their own right. I would advise learning to use plain old and potentially dangerous pointers first.

Good luck!

Share this post


Link to post
Share on other sites
I think ive created a monster ha ha. Thanks for all the advice.
So basically this is a summation of the uses of pointers:

- pass by pointer or reference (personal preference really but reference being the better option) for functions so large amounts of memory arnt being passed around ram.
- polymorphism (I think the main reason to use pointers)
- and lastly, keeping variables alive when they become out of scope.

again thanks for the help!

Share this post


Link to post
Share on other sites
Quote:
Original post by Helo7777
- polymorphism (I think the main reason to use pointers)


Also works with references.

Quote:
- and lastly, keeping variables alive when they become out of scope.


No. Either the pointer is used on an auto-value, which will then die on its own without being kept alive, or it's used on a non-auto-value, which will then stick around regardless of whether you're using a pointer or not.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Quote:
- and lastly, keeping variables alive when they become out of scope.


No. Either the pointer is used on an auto-value, which will then die on its own without being kept alive, or it's used on a non-auto-value, which will then stick around regardless of whether you're using a pointer or not.


I assume he's thinking of dynamic allocation, where a pointer value is merely used to communicate what was dynamically allocated or should be deallocated. [smile]

Share this post


Link to post
Share on other sites
It depends on what the programmer wants to do. Members as pointers means that they will have some memory allocated some time during the lifetime of the class (the memory maybe allocated at the beginning, sometime in the middle, or near the end). Whereas members that are not pointers will have the memory allocated right when the class instantiated. For an example of members as pointers, look at a class which implements a linked list or a binary tree. Most of the classes that you will create will be members as non-pointers. Why? Because for a beginner, that's all you'll need for now [smile].

Don't put too much emphasis on the concept for now. It'll come to you as you program more. Especially when implementing certain Data Structures (such as linked list and binary tree).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this