Jump to content

  • Log In with Google      Sign In   
  • Create Account


C++ pointer strangeness


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 jdub   Members   -  Reputation: 419

Like
0Likes
Like

Posted 05 November 2012 - 08:47 PM

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

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.

Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9565

Like
4Likes
Like

Posted 05 November 2012 - 08:51 PM

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.

#3 Servant of the Lord   Crossbones+   -  Reputation: 18501

Like
2Likes
Like

Posted 05 November 2012 - 08:57 PM

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. Posted Image
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#4 Trienco   Crossbones+   -  Reputation: 2125

Like
7Likes
Like

Posted 05 November 2012 - 11:31 PM

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

#5 Álvaro   Crossbones+   -  Reputation: 12923

Like
6Likes
Like

Posted 06 November 2012 - 04:23 AM

Or you can use a standard algorithm:
string my_string("some text");
reverse(my_string.begin(), my_string.end());


#6 NightCreature83   Crossbones+   -  Reputation: 2745

Like
0Likes
Like

Posted 06 November 2012 - 05:48 AM

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

Edited by NightCreature83, 06 November 2012 - 05:51 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#7 Servant of the Lord   Crossbones+   -  Reputation: 18501

Like
0Likes
Like

Posted 06 November 2012 - 10:07 AM

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. Posted Image

Edited by Servant of the Lord, 06 November 2012 - 10:07 AM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#8 Bregma   Crossbones+   -  Reputation: 5008

Like
0Likes
Like

Posted 06 November 2012 - 10:43 AM

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

Stephen M. Webb
Professional Free Software Developer

#9 Bacterius   Crossbones+   -  Reputation: 8533

Like
0Likes
Like

Posted 06 November 2012 - 05:24 PM

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.

The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#10 chunkyguy   Members   -  Reputation: 149

Like
1Likes
Like

Posted 06 November 2012 - 10:11 PM

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

#11 Moonkis   Members   -  Reputation: 273

Like
1Likes
Like

Posted 07 November 2012 - 08:02 AM

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.

This, or using a pointer to pointer has the same result: void function(Foo** foo) then to assign something new: *foo/(*foo) = <VALUE>




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS