Sign in to follow this  
jdub

C++ pointer strangeness

Recommended Posts

jdub    459
So here is a little code I wrote for class:
[CODE]
void reverseString(char* const src, char* reversed)
{
reversed = new char[strlen(src)+1];
for(unsigned int i = 0; i < strlen(src) - 1; i++)
{
unsigned int resIndex = strlen(src) - i - 1;
reversed[resIndex] = src[i];
}
reversed[strlen(src)] = '\0';
}

int main(void)
{
char* original = "Hello World!";
char* reversed = NULL;
reverseString(original, reversed); //reversed should be assigned in here
cout << original << endl << reversed; //however reversed is still NULL here?!

cin.get();
return 0;
}
[/CODE]

The code should assign reversed to a value inside reverseString(). And, at the end of reverseString() before the program branches back to main() the pointer is assigned to the correct value. However, upon reaching cout, the reversed pointer is NULL again. Can someone explain what is going on here?

Share this post


Link to post
Share on other sites
SiCrane    11839
You're passing the pointer by value. Assignments to the pointer inside the function won't be visible to the calling function. You can try using a reference to a pointer (char *&) instead.

Share this post


Link to post
Share on other sites
Pointers hold the address of the object to alter.
You are passing in the address of the object to alter into the function - the address you are passing is 'NULL'.

The pointer in the function's parameter is a different variable - it's told the 'NULL' address.
It then changes [u]its[/u] address (but not the address of the original pointer) to whatever 'new' returns.
The original pointer's address is still set to zero.

Then it exits.

Perhaps you want a pointer to a pointer?
[code]void reverseString(char* const src, char** reversed)
{
*reversed = new blah;
}

char *reversed = NULL;
reverseString(blah, &reversed);
[/code]

The better solution would be to just [i]return[/i] the pointer from the function.
[code]char *reverseString(char* const src)
{
char *reversed = new blah;
return reversed;
}

char *reversed = reverseString(blah);
[/code]

The even better solution is to use std::strings, if you have them available, since you already mentioned you are using C++ in the thread's title. [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]

Share this post


Link to post
Share on other sites
NightCreature83    5002
[quote name='Servant of the Lord' timestamp='1352170626' post='4997848']
[code]void reverseString(char* const src, char** reversed)
{
*reversed = new blah;
}

char *reversed = NULL;
reverseString(blah, &reversed);
[/code]
[/quote]
The C++ way would be to use a reference to a pointer so that you can just assign to it in the function if you want to keep the interface the same. And would look like this:
[code]void reverseString(char* const src, char*& reversed)
{
reversed = new blah;
}
char *reversed = NULL;
reverseString(blah, reversed);
[/code] Edited by NightCreature83

Share this post


Link to post
Share on other sites
Yea, SiCrane already mentioned that a minute or two before I submitted my post.
I had never heard of reference to pointer before his post! Though personally, using either of them (pointer to pointer, reference to pointer) would probably be an indicator of bad overall design of the function. [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
Bregma    9199
While one traditional way of solving this C-language problem is to pass the [i]reversed[/i] pointer by pointer, a better design and still traditional C-language solution would be to return [i]reversed[/i] as the function return value instead.
[code]
char *reverseString(char *src)
{
int len = strlen(src);
reversed = new char[len+1];
for (int i = 0; i < len; ++i)
{
int resIndex = len - i - 1;
reversed[resIndex] = src[i];
}
reversed[len] = '\0';
return reversed;
}

int main()
{
char *original = "Hello World!";
char *reversed = reverseString(original); // reversed is allocated in here
cout << original << "\n" << reversed << "\n";
cin.get();
delete[] reversed;
}
[/code]

Share this post


Link to post
Share on other sites
Bacterius    13165
Personally, if I was doing this in C, I'd make my function accept an already allocated output pointer as argument, to write the reversed string in (and also ensure the original string could be passed as an output so that the operation can be done in-place). It just doesn't feel right to allocate memory inside the function itself.

Share this post


Link to post
Share on other sites
chunkyguy    149
You can just try is yourself by printing the pointers and everything should be clear:

[CODE]printf("BEF: %p\n",reversed);
reversed = new char[strlen(src)+1];
printf("AFT: %p\n",reversed);[/CODE]

and in main()
[CODE]printf("START: %p\n",reversed);
reverseString(original, reversed); //reversed should be assigned in here
printf("END: %p\n",reversed);[/CODE]

On my machine it prints something this:
[CODE]START: 0x0
BEF: 0x0
AFT: 0x7fdc68c000e0
END: 0x0[/CODE]

And now read the answers posted above

Share this post


Link to post
Share on other sites
PureSnowX    275
[quote name='SiCrane' timestamp='1352170313' post='4997845']
You're passing the pointer by value. Assignments to the pointer inside the function won't be visible to the calling function. You can try using a reference to a pointer (char *&) instead.
[/quote]
This, or using a pointer to pointer has the same result: void function(Foo** foo) then to assign something new: *foo/(*foo) = <VALUE>

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