Page 2 of 2

Posted: Mon Apr 16, 2007 10:04 pm
by bigfish
Yikes... When dealing with pointers, relying on things like "it just works" is a bad idea. You could be lucking out at the moment but when running it under slightly different conditions, you could be trampling some memory that you shouldn't be touching. When you're passing in a variable like this:

void function(int &a) { ... }

you're using a reference, not a pointer. It's basically letting the compiler figure out the pointer stuff for you. Doing "a = 2" will indeed set the value of the variable back in the location where you called the function. When you use an actual pointer like this:

void function(int *a) { ... }

doing the same "a = 2" is not going to change the value of a back where you called the function. a is a pointer to an int, so doing "a = 2" changes the location that the pointer is pointing to. If you're trying to change the value of the variable that you passed to the function you need to dereference the pointer by doing "*a = 2", just like Luben and thephoenix said. And of course back in the initial function call, you need to pass the variable like so:

function(&a);

In that case, & is the "address of" operator, not the reference operator. Getting the address of a variable gives you a pointer. Isn't C++ great? ;) Personally, I never use references because of that stupid syntax. I cut my teeth on C where all you had was pointers and no references. And damnit, things made sense!

To sum it all up, here's an example:

int a = 0;
refFunc(a); // Good. a now equals 1.
ptrFunc1(&a); // Good. a now equals 2.
ptrFunc2(&a); // Doesn't work. a still equals 2.
ptrFunc1(a); // This should be a compiler error.

refFunc(int &arg) {
arg = 1;
}

ptrFunc1(int *arg) {
*arg = 2;
}

ptrFunc2(int *arg) {
arg = 3; // Setting the value of the pointer, not the intended variable.
}

Make sense?

Posted: Mon Apr 16, 2007 11:58 pm
by zeno60
http://cslibrary.stanford.edu/104/

Lets let Binky explain.

Posted: Tue Apr 17, 2007 5:23 pm
by twentytortures
Thanks for all the help, I'm understanding pointers and things better now. I've been able to pass almost everything I want into functions now. I just have one thing that I'm having problems with. I want this code in a function:

Code: Select all

video::IVideoDriver* driver = device->getVideoDriver();
I declare my function like this:

Code: Select all

void function(video::IVideoDriver* driver)
But I'm confused how to get it to modify the original driver variable that I passed in. I tried doing this:

Code: Select all

function(&driver)
But I get a compile error. I also had the code in the function looking like this:

Code: Select all

void function(video::IVideoDriver* driver)
{
     &driver = device->getVideoDriver();
}
And I still get a compile error. Do I have the wrong syntax?


EDIT:
Oh, and thanks for Binky, that was seriously one of the most helpful things I have ever seen. Are there any other Binky videos?

Posted: Wed Apr 18, 2007 1:44 pm
by bigfish
Yup, you need:

Code: Select all

void function(video::IVideoDriver* driver)
{
     *driver = device->getVideoDriver();
}
Using *driver dereferences the pointer so you're dealing with the object that's being pointed to, not the pointer itself.

Posted: Wed Apr 18, 2007 3:50 pm
by twentytortures
Lol, didn't even think to try that. Even after binky told me how it works too. Thanks!

Posted: Wed Apr 18, 2007 6:29 pm
by Nalin
Wow. This thread confuses the heck out of me.

Code: Select all

void myFunc()
{
  CMyClass* feh = 0;

  myFunc2( &feh );
}

void myFunc2( CMyClass** test )
{
  *test = new CMyClass();
}
If I am correct in understanding what is going on, use a pointer to a pointer. That is how you modify the original pointer.

You have a pointer. You pass the address of the pointer in memory to a function. That function takes a pointer... to a pointer! Then, by altering the value of the pointer in the function, you are actually modifying where the pointer you passed points.

Code: Select all

------------
| Pointer1 | ----------> some place in memory
| CMyClass | points to
------------

=======================================

myFunc( Pointer1 );
void myFunc( CMyClass* test )
{
}

------------
| Pointer1 | ----------> some place in memory
| CMyClass | points to   ^
------------             |
                         |
------------             |
| test     |--------------
| CMyClass | points to
------------

Calling *test changes "some place in memory"

=======================================

myFunc( &Pointer1 );
void myFunc( CMyClass** test )
{
}

------------
| Pointer1 | ----------> some place in memory
| CMyClass | points to
------------
     ^
     |
------------
| test     |
| CMyClass |
------------

Calling *test changes "Pointer1"

Posted: Thu Apr 19, 2007 1:29 am
by bigfish
I think the goal of most of these posts has been to modify the value of a variable being passed to a function, not change where a pointer is pointing to. If you did actually want to do what you showed in your code though, it's much cleaner to just return a pointer from the function rather than using an "out"-style argument. Although come to think of it, it's pretty much *always* cleaner to use returns instead of passing in pointers just to muck with stuff. Anyway, I'd say to do this to achieve the same thing as what you've got:

Code: Select all

void myFunc()
{
    CMyClass* feh = myFunc2();
}

CMyClass* myFunc2()
{
    return new CMyClass();
}

Posted: Thu Apr 19, 2007 12:54 pm
by Midnight
twentytortures wrote: Oh, and thanks for Binky, that was seriously one of the most helpful things I have ever seen. Are there any other Binky videos?
http://cslibrary.stanford.edu/


no.