C++ pointer strangeness

Started by
9 comments, last by PureSnowX 11 years, 5 months ago
So here is a little code I wrote for class:

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;
}
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;
}


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?
J.W.
Advertisement
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.
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 its 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?
void reverseString(char* const src, char** reversed)
{
*reversed = new blah;
}

char *reversed = NULL;
reverseString(blah, &reversed);


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

char *reversed = reverseString(blah);


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. wink.png
Of course reversing a string in C++ is kind of boring:


string original("some text");
string reversed(original.rbegin(), original.rend());



It also avoids all the other bugs and issues in the C-style implementation above (loop too short, calling strlen on every single iteration, passing pointer by value, the dreadful "function internally allocating memory" thing).
f@dzhttp://festini.device-zero.de
Or you can use a standard algorithm:
string my_string("some text");
reverse(my_string.begin(), my_string.end());

void reverseString(char* const src, char** reversed)
{
*reversed = new blah;
}

char *reversed = NULL;
reverseString(blah, &reversed);


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:
void reverseString(char* const src, char*& reversed)
{
reversed = new blah;
}
char *reversed = NULL;
reverseString(blah, reversed);

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

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. smile.png
While one traditional way of solving this C-language problem is to pass the reversed pointer by pointer, a better design and still traditional C-language solution would be to return reversed as the function return value instead.

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;
}
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;
}

Stephen M. Webb
Professional Free Software Developer

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.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

You can just try is yourself by printing the pointers and everything should be clear:

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


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


On my machine it prints something this:
START: 0x0
BEF: 0x0
AFT: 0x7fdc68c000e0
END: 0x0


And now read the answers posted above

This topic is closed to new replies.

Advertisement