Skip to main content
gamedev.net
🔒 Locked

A reference to a pointer?

Started by Thunder_Hawk 20 replies 450+ views
Original Post
Thunder_Hawk
Thunder_Hawk
I''m wanting to make a function that will take in a pointer and later reassign that pointer in the function. It occured to me that I wouldn''t be able to say:
void ReassignPointer (unsigned char* pointer) {
    pointer = differentPointer;
}
 
because the pointer would be passed in by value. Correct? The remedy for this, I would think, would be to take in a reference to a pointer. Only one problem...How do I declare that? Or better yet, is that legal? Thanks for any help. _____________________________ And the Phoenix shall rise from the ashes... --Thunder_Hawk -- ¦þ ______________________________
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
Ecko
Ecko
void function( unsigned char** ppThingy )
{
&ppThingy = differnt_pointer;
}
-----------------------------------------------------------"People who usualy use the word pedantic usualy are pedantic!"-me
Miserable
Miserable
quote:
Original post by Ecko
void function( unsigned char** ppThingy )
{
&ppThingy = differnt_pointer;
}

I presume you mean *ppThingy = different_pointer?
Thunder_Hawk
Thunder_Hawk
Didn''t think of that... Still, I think a reference to a pointer would look cleaner. Anyone know if that''s possible?
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
Thunder_Hawk
Thunder_Hawk
Oops, a little slow on the gun. Thanks AP, that''s what I was looking for.
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
Shannon Barber
Shannon Barber
What''s not permitted is a pointer to a reference.
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
nymusdc
nymusdc
correct me if I''m wrong...

I think the problem with
void ReassignPointer (unsigned char* pointer) {
pointer = differentPointer;
}
is that at the end of the function, ''differentPointer'' does not exist so pointer is not pointing to anything! so dereferencing ''pointer'' will cause a segmentation fault. It is a variable like any other and will be destroyed once it goes out of scope.

Maybe if ''differentPointer'' was declared at global scope?

or you could say: pointer = new unsigned char,
that way you know that the pointer is pointing to real data at the end of the function so no leaks.

Believe in Dreams
Inspired by Dreamcast
Thunder_Hawk
Thunder_Hawk
nyumudc:
Here''s my function:

  
void AddAlpha (COLORC r, COLORC g, COLORC b, unsigned char* &NoAlpha, unsigned long imageSize) {
unsigned char* Alpha = new unsigned char[imageSize*4];
// Add room for alpha component

for (unsigned long i = 0, unsigned long j = 0; i < imageSize*3; i+=3, j+=4) {
Alpha[j] = NoAlpha[i]; Alpha[j+1] = NoAlpha[i+1]; Alpha[j+2] = NoAlpha[i+2];
// Copy RGB value

Alpha[j+3] = (NoAlpha[i] == r && NoAlpha[i+1] == g && NoAlpha[i+2] == b)? 0 : 255;
// If "Special" color, make transparent

}
delete [] NoAlpha; // Erase old data

NoAlpha = Alpha; // Make passed pointer point to data with alpha component

}

This code is completely untested and probably has a bug somewhere (I just guessed for the time being whether 0 or 255 is opaque), but since my "differentPointer" is made on the free store I think its free of the problem you mentioned. However, I''m getting tired so I could be wrong...
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
nymusdc
nymusdc
Sorry about the multiple post b4...troubled connection.

Since you say you haven''t tested the code, I can''t guarantee anything, but...

I would recommend you include a NULL terminator in the assignment:
unsigned char* Alpha = new unsigned char[imageSize*4];

to

unsigned char* Alpha = new unsigned char[imageSize*4 + 1];

You don''t have to pass the parameter as:

unsigned char* &noAlpha.

Since pointers and references are equivalent and here we are dealing with a primitive type (char), you could just pass it as:

unsigned char* noAplha.

Pointers can ALWAYS be modified within functions, unless they are passed as:

const unsigned char* noAlpha -> you will not be able to delete [] noAlpha

or

unsigned char const *noAlpha -> you will not be able to change noAlpha = alpha.

So your code is good, just ditch the ampersand and if the loop algorith is okay, you shouldn''t have too much of a problem.

I have tried it with a dynamic string and the pointer sent to the function ''is'' changed correctly. Here''s the simple code I tested with:

#include <iostream.h>
#include <string.h>

void call(char* aChar) {
cout << aChar << endl;
delete [] aChar;
char* temp = new char[strlen("Hello")+1];
strcpy(temp, "Hello");
cout << "About to return" << endl;
aChar = temp;
}
int main() {
char temp[10];

cin >> temp;

char* aChar = new char[strlen(temp)];

cout << "you entered: " << aChar << endl;

call(aChar);

cout << aChar << endl;

return 0;
}

Believe in Dreams
Inspired by Dreamcast
Arild Fines
Arild Fines
quote:
Original post by nymusdc
Sorry about the multiple post b4...troubled connection.


Don''t apologize - delete the redundant posts instead.
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Carrot
Carrot
quote:
Original post by nymusdc
.. 'differentPointer' does not exist so pointer is not pointing to anything! so dereferencing 'pointer' will cause a segmentation fault. differentPointer is a variable like any other and will be destroyed once it goes out of scope.



Sorry, but this isn't correct. Afterall, this is how the new/malloc operators work!

There is nothing wrong with:

int* GetSomeMemory()
{
int* p = new int[10];
return p;

}

even though the pointer goes out of scope, the memory block doesn't. This is the cause of memory leaks!

quote:
Original post by nymusdc
I would recommend you include a NULL terminator in the assignment:
unsigned char* Alpha = new unsigned char[imageSize*4];

to

unsigned char* Alpha = new unsigned char[imageSize*4 + 1];



If he's not using the array as a character buffer there is now need. He knows the array bounds.


quote:
Original post by nymusdc
You don't have to pass the parameter as:

unsigned char* &noAlpha.

Since pointers and references are equivalent and here we are dealing with a primitive type (char), you could just pass it as:

unsigned char* noAplha.



This isn't true either! Pointers are not equivalent to references. Using the method you suggest would not alter the calling functions version of the pointer.
The reference is needed, in fact if its ommited then an exception is going to raised because the function deletes the block of code pointed to by the parameter.



[edited by - carrot on December 9, 2002 8:21:10 AM]
Trienco
Trienco
quote:
Original post by nymusdc
Since pointers and references are equivalent and here we are dealing with a primitive type (char), you could just pass it as:

unsigned char* noAplha.

Pointers can ALWAYS be modified within functions, unless they are passed as:

const unsigned char* noAlpha -> you will not be able to delete [] noAlpha


and here (as above) is where you''re missing the point. he wants to change the pointer itself, not the variable pointed to and exactly this pointer is a copy of the real pointer. look at it this way: youre always calling by value, just in this case your value is a pointer. he can change the pointer as much as he likes, but he''s changing a copy and the program wont care.

the only way to change the pointer is giving either a pointer to the pointer (ugly) or a reference to the pointer.

f@dzhttp://festini.device-zero.de
nymusdc
nymusdc
Thanks for the correction Trienco.

I tried the function again and indeed, the pointer IS passed by value and the function works with a different pointer from the one passed to it.

I''m trtying to see if I can get the reference to a pointer thing working...

How does one insert code segments in a text box?

sample out put from a function I tested with:
In Main
Address of Pointer: 0xbffff784
Contents of Pointer: 50

Inside function...
Address of Parameter: 0xbffff770
Contents of Parameter: 50
Deleting Parameter...

Address of Parameter: 0xbffff770
Creating new pointer with new contents...
Address of new Pointer: 0xbffff764
Reassigning old pointer...

Address of Pointer: 0xbffff770
Contents of Pointer: 100

Returning to main...

After call to aFunction...

Address of Pointer: 0xbffff784
Contents of Pointer: 100

Believe in Dreams
Inspired by Dreamcast
Stoffel
Stoffel
quote:
Original post by nymusdc
I tried the function again and indeed, the pointer IS passed by value and the function works with a different pointer from the one passed to it.


All parameters are passed by value in the most literal sense. The only type that isn''t is an actual C++ reference (which is actually a pointer internally).

quote:

I''m trtying to see if I can get the reference to a pointer thing working...


It was shown earlier: func (Type*& rTypePtr)

quote:

How does one insert code segments in a text box?


[ source ] and [ /source ] without the spaces.

HTTP 500 retry 1..
nymusdc
nymusdc
True, passing the pointer as aFunction(int* &anIntPointer) passes the address of the original pointer but how do you reassign it?

anIntPointer = newIntPointer -> anIntPointer retains its original address

In Main
Address of Pointer: 0xbffff784
Contents of Pointer: 50

Inside function...
Address of Parameter: 0xbffff784
Contents of Parameter: 50
Deleting Parameter...

Creating new pointer with new contents...
Address of new Pointer: 0xbffff764
Reassigning old pointer...

Address of Pointer: 0xbffff784 //should have become 0xbffff764 right?!
Contents of Pointer: 100

Returning to main...
After call to aFunction...

Address of Pointer: 0xbffff784
Contents of Pointer: 100


Believe in Dreams
Inspired by Dreamcast
Stoffel
Stoffel
Do you need a triple pointer for some reason? This program runs without error, therefore the pointer value is changed within the function:

  
#include <cassert>

using namespace std;

void mutate (int *&rIntPtr)
{
rIntPtr = reinterpret_cast<int*> (0xdeadbeef);
}

int main ()
{
int *pInt = 0;
assert (0 == pInt);
mutate (pInt);
assert (reinterpret_cast<int*> (0xdeadbeef) == pInt);
return 0;
}

Are you trying to accomplish something more than this?
Thunder_Hawk
Thunder_Hawk
quote:
Original post by nymusdc
True, passing the pointer as aFunction(int* &anIntPointer) passes the address of the original pointer but how do you reassign it?

anIntPointer = newIntPointer -> anIntPointer retains its original address

In Main
Address of Pointer: 0xbffff784
Contents of Pointer: 50

Inside function...
Address of Parameter: 0xbffff784
Contents of Parameter: 50
Deleting Parameter...

Creating new pointer with new contents...
Address of new Pointer: 0xbffff764
Reassigning old pointer...

Address of Pointer: 0xbffff784 //should have become 0xbffff764 right?!
Contents of Pointer: 100

Returning to main...
After call to aFunction...

Address of Pointer: 0xbffff784
Contents of Pointer: 100


Believe in Dreams


I believe I see the problem here...instead of outputting the address of the pointer (this should never change if you think about it), output the contents of the pointer instead (the address of the variable it points to) like this.

int* somepointer; //just for instance
cout << somepointer << '\n'; //see what I mean now?

If you output the pointer like that, I'm sure you'll see the results you expect.

[EDIT] int* instead of char*, char* would be interpreted as a string, not what I was intending to show you

_____________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________


[edited by - Thunder_Hawk on December 9, 2002 7:05:59 PM]
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
nymusdc
nymusdc
I had already tried sending output as you suggested ie

int* aPointer
cout << aPointer << endl; //for pointer
cout << *aPointer << endl; //for contents of pointer

what happened was that the pointer in main as well as the pointer in the function produced the same output. When I assigned data to the pointers using 'new', the addresses changed but were still identical! I think what happens is that "cout << aPointer " gives the address of the stack and when you create data using 'new' the address output is that of the heap?? Here is the output I got:
**********************************************
In Main
Address of Pointer: 0x4023cc18 //HERE IS STACK ADDRESS?
Adding data to pointer...
Address of Pointer: 0x80492b8 //WATCH THIS ADDRESS!
Contents of Pointer: 50

Inside function...
Address of Parameter: 0x80492b8
Contents of Parameter: 50
Deleting Parameter...

Creating new pointer with new contents...
Address of new Pointer: 0x400157cc //STACK ADDRESS AGAIN?
Assigning new data to new pointer...
Address of new Pointer: 0x80492b8 //SEE! IDENTICAL HERE!
Reassigning old pointer...

Address of Pointer: 0x80492b8
Contents of Pointer: 100

Returning to main...
After call to aFunction...

Address of Pointer: 0x80492b8
Contents of Pointer: 100
****************************************

what I used in the last post was: "cout << &aPointer" to output the address of the pointer.

Here's the code I'm testing with:

        #include <iostream.h>

/* A revised version. Maybe my point will be better illustrated */

void aFunction(int* &anIntPointer) {
cout << endl << "Inside function..." << endl;
cout << "Address of Parameter: " << &anIntPointer << endl;
cout << "Contents of Parameter: " << *anIntPointer << endl;
cout << "Deleting Parameter..." << endl<< endl;
delete anIntPointer;
cout << "Address of Parameter: " << &anIntPointer << endl;
cout << "Creating new pointer with new contents..." << endl;
int* newInt;
cout << "Address of new Pointer: " << &newInt << endl;
cout << "Assigning new data to new pointer..." << endl;
newInt = new int(100);
cout << "Address of new Pointer: " << &newInt << endl;
cout << "Reassigning old pointer..." << endl<< endl;
anIntPointer = newInt;
*anIntPointer = *newInt;
cout << "Address of Pointer: " << &anIntPointer << endl;
cout << "Contents of Pointer: " << *anIntPointer << endl<< endl;
cout << "Returning to main..." << endl;
}

int main() {
cout << "In Main" << endl;

int *anIntPointer;
cout << "Address of Pointer: " << &anIntPointer << endl;
cout << "Adding data to pointer..." << endl<< endl;
anIntPointer = new int(50);
cout << "Address of Pointer: " << &anIntPointer << endl;
cout << "Contents of Pointer: " << *anIntPointer << endl;

aFunction(anIntPointer);

cout << "After call to aFunction..." << endl<< endl;
cout << "Address of Pointer: " << &anIntPointer << endl;
cout << "Contents of Pointer: " << *anIntPointer << endl;

return 0;
}


[edited by - nymusdc on December 9, 2002 8:39:28 PM]

[edited by - nymusdc on December 9, 2002 8:44:14 PM]

[edited by - nymusdc on December 9, 2002 8:45:57 PM]
Inspired by Dreamcast
Thunder_Hawk
Thunder_Hawk
Now that I see your code I think I know what''s happening...

The "stack addresses" you noted may be that I don''t know, but I do know that the value is simply the random memory pointed to by an uninitialized pointer. Now aside from that, it''s perfectly legal for the new pointer to point to the same spot as the old pointer because the old pointer has recently been deleted. I think the new keyword has a natural tendancy to do this anyway (I''ve seen a few examples of this happening). Anyway, try creating the new pointer before deleting the old pointer. Hopefully then you will see what you expected.

_____________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________
______________________________________________________________________________________The Phoenix shall arise from the ashes... ThunderHawk -- ¦þ"So. Any n00bs need some pointers? I have a std::vector<n00b*> right here..." - ZahlmanMySite | Forum FAQ | File Forma
nymusdc
nymusdc
How about ''your'' code. Did you get it to work? How did you do it?



Inspired by Dreamcast
Inspired by Dreamcast

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.