Sign in to follow this  
cherryhouse

Pointers

Recommended Posts

I have been wondering about pointers, ever since I learned about them. I realize they can hold a value and an address to a value. What I was wondering though was, what exactly would you need to use the address of a value for? I have red peoples references, tutorials, a few books "view" on pointers, but still don't understand why exactly they are used. The books I have read all say pointers are extremely hard to grasp, but I think after 5 months of programming and 3 months of trying to understand them(not straight), I would at least know a bit about them but it feels like I haven't made any progress. I am going to continue to read this chapter on pointers now. Hope I budge this time.

Share this post


Link to post
Share on other sites
They're usually used for keeping track of memory allocated on the heap. Because of the limited amount of stack-based memory, you certainly wouldn't want to allocate 2 megabytes worth of data on it. Instead, you would ask Windows (or whatever the underlying OS is) to store the memory on the computer's RAM chip(s) directly.

Windows then provides you with a (virtual) pointer to the allocated memory block.


int main(int argCount, char* args[])
{
char arrayA[2097152];

// VS

char* arrayB = new char[2097152];

delete[] arrayB;

return 0;
}


Also pointers can be used in place of references (not recommended, exists mainly for backward compatability with C code):


void FunctionA(const BigObject* object)
{
cout << object->value << "\n";
}

// VS

void FunctionB(BigObject object)
{
// The entire object is copied - Ouch!
cout << object.value << "\n";
}

int main(int argCount, char* args[])
{
BigObject object;

object.value = 5;

FunctionA(&object);
FunctionB(object);

return 0;
}


The idea being that it is easier to give someone your residential address rather than give them your entire house.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
A point to keep in mind about Wavarian's post is that even though it is technically true, it would be a little better to state that the run-time libraries of the compiler are taking care of the 'new'ing of the memory on the heap. These will call Windows when they need to, but they will not usually call Windows GlobalAlloc or other memory functions until they have exhausted the memory they obtained from Windows in their last call. Dozens to thousands (or more) of 'new' items may have been created between those points.

Keeping that in mind will help you a little further down the road.

Share this post


Link to post
Share on other sites
The usefulness of pointers becomes much easier to see when you reach the chapters on Classes, Inheritence, and -- more importantly -- Polymorphism. Just stick with it, and all will be revealed once you begin to learn about polymorphism ;-)

Trust me; when I was learning pointers, I was like "wtf do I need this for?!" then I learned about polymorphism and virtual functions, and gave a big "AHHHHH now I see... cool!"

Good luck to you in your endeavors! :-D

Share this post


Link to post
Share on other sites
Ok, im just reading my book and came to the conclusion:

You can create a struct with 4 values, create a pointer to reference the struct and send it over a network and the user on the other end would recieve the values of the struct?

Share this post


Link to post
Share on other sites
Here's another way of looking at pointers. This is a hex dump of a chunk of memory. The first column contains the address of the memory that contains the values shown in the next 4 columns. The last column is an ansi translation of the values from the middle section.


001C4B28 | 00000000 001C4B90 00000000 00000000 | .....K..........
001C4B38 | 001C4B30 00000000 001C4B38 00000000 | 0K......8K......
001C4B48 | 001C4B40 00000000 001C4B48 CDCDCDCD | @K......HK......
001C4B58 | CDCDCDCD CDCDCDCD 001C4B50 CDCDCDCD | ........PK......
001C4B68 | CDCDCDCD CDCDCDCD CDCDCDCD CDCDCDCD | ................
001C4B78 | CDCDCDCD CDCDCDCD 001C4B60 CDCDCDCD | ........`K......
001C4B88 | CDCDCDCD CDCDCDCD 001C4B80 CDCDCDCD | .........K......
001C4B98 | CDCDCDCD CDCDCDCD CDCDCDCD CDCDCDCD | ................
001C4BA8 | CDCDCDCD CDCDCDCD | ........


A pointer would be a variable that held the address of such a chunk. This chunk is organized as 32 bit integers, so we could write

int *mypointer;

mypointer = 0x001C4B28;

although more likely the assignment would utilize "new" or "malloc" or some other allocation function, eg. GlobalAlloc, HeapAlloc, etc.

A pointer "points to" a chunk of memory. A pointer is "dereferenced" in order to access the values stored in that chunk of memory. In the above, the variable mypointer points to the chunk of memory beginning at the address 0x001C4B28. If the variable mypointer is dereferenced, the value obtained is 0.

Because mypointer is a variable, we can use operators on it. For example,

mypointer++;
mypointer -= 1;
mypointer += 3;

These operators change the value of the pointer itself, not the values stored in the memory pointed to. But, it's important to remember that pointers are incremented and decremented in steps equal to the size of the data type they point to. So, with the mypointer example, that would be 4, the size of an int.

After the instruction, mypointer++; mypointer holds the value 0x001C4B2C (0x001C4B28 + 4) which points to memory that contains the value 0x001C4B90. Follow that with the instruction, mypointer += 3; and mypointer holds the value 0x001C4B38 (0x001C4B28 + 0x10) which points to memory that contains the value 0x001C4B30. Notice that is the start of next row down.

At any rate, there is more than can be said for all this.

Share this post


Link to post
Share on other sites
Eaw. :-'

Pointers arent generally something you pass over a network, AFAIK (I havn't done any network programming yet though). If you are reading a beginner's book, then they most likely mean that pointers are a very fast way to pass large amounts of data into a function (not over a network).

For instance:

Say you have a struct called TenNumbers that looked like so...

struct TenNumbers
{
int one;
int two;
int three;
int four;
int five;
int six;
int seven;
int eight;
int nine;
int ten;
};








Now say you created an instance of TenNumbers in main(), like so...

int main()
{
TenNumbers example;








Now, say you wanted to find the average of all ten numbers, using a function called Average(). It might look something like this...

int Average(TenNumbers data)
{
//add up all ten numbers and divide by ten here
return result;
}








Now, when you call Average(example) from main(), Average() gets it's own copy of TenNumbers, and it has to copy every single number, one-by-one, over into the new function. This is extreme overkill: you could simply use main()'s copy! This is rectified with pointers:

int Average(TenNumbers* data)
{
//do stuff
return result;
}

int main()
{
TenNumbers example;
int average;

average = Average(&example); //this passes the 'address' of the data,
//instead of copying over all the data.
return 0;
}








So, in essence, a pointer is a finger, "pointing" at the data in main() and saying "F*** it; I'm not gonna copy all this! Just use the data from over -there!-"
(at least in the context of this example)

Edit: hmm... I really like that last thought... I may make it into my sig...

Share this post


Link to post
Share on other sites
Pointers hurt my head at one point but now I find reasons to use tripple pointers and crap.

Heres on of the thousands of needs for pointers

I load 10,000 textures at 500kb each. Now thats one huge block of memory!

Say I have a Monster I want to draw in a game that uses 6000 of those textures.

The more ideal solution to this is to declare 6000 pointers of that texture struct- whatever and point to whats already made

whats better? making pointers 4bytes x 6000 or making the same texture = that huge textures array you made.... which could be 300 bytes per texture struct you make

soo...

[source="cpp"]
struct dingleberries
{
int berrysize;
int berrys[1000];
bool isfruity;
};

void main()
{
dingleberries batch[100]; //Will be some big size in memory
dingleberries *berrytocheckforfruityness; //The pointing death berry

//AH heres another use.... this will also start our iterator
berrytocheckforfruityness = &batch[0];

//Instead of calling that subset we can just call the pointer we made to access it so its sorta cleaner.

//Instead of making a regular dingleberry we point to one...
if(berrytocheckforfruityness->isfruity)
printf("Yum");

//now for a iterator
for(int i = 0; i < 100; i++, berrytocheckforfruityness++) //Increments to the next address in memory soooooo 0xF3D39432->0xF3D39433
{

//2nd advantage to pointer here
//batch[i].berry[50] = 0;
berrytocheckforfruityness->berry[40] = 0;

}
}


In general pointers dont make since until you use them correctly more. Now when you start making 3D stuff or 2D stuff you would think about pointers in a filtering out textures already loaded like I did.

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