Beginner: Variable loses last letter upon return from function

Thread Solved

Join Date: Aug 2009
Posts: 7
Reputation: NeoFryBoy is an unknown quantity at this point 
Solved Threads: 0
NeoFryBoy NeoFryBoy is offline Offline
Newbie Poster

Beginner: Variable loses last letter upon return from function

 
1
  #1
Aug 8th, 2009
Quick background: I'm working on Project Euler and made a palindrome checker. I needed to convert integers to strings. itoa() kept giving random values (9 gave 9 or 90, etc...), so I decided to make my own, and ran into a problem. I have fixed it, but could somebody explain what caused the problem and why the fix works?

Broken Code: The below code creates a stringstream inputs the number then puts that into a string and then into a char. The problem is it would chop the last number off when returning the char. (The buffer holds the 99800 value but the receiving variable numaschar = strItoA(num); becomes 9980.)

  1. char* strItoA(int number)
  2. {
  3. std::ostringstream sin;
  4. sin << number;
  5. std::string val = sin.str();
  6.  
  7. size_t length;
  8. char buffer[val.size()+1]; //add one for the zero terminator
  9. length=val.copy(buffer,val.length(),0); //do the transfer and grab the last position
  10. buffer[length]='\0'; //zero terminate!!
  11. return buffer;
  12. }

The Fix:
  1. char* buffer; //moved outside of function and given reference
  2.  
  3. char* strItoA(int number)
  4. {
  5. //Same...
  6.  
  7. buffer = new char [val.size()+1]; //added to keep buffer dynamic
  8. //char buffer[val.size()+1]; //removed
  9. //Same...
  10. }

Thanks.
Last edited by NeoFryBoy; Aug 8th, 2009 at 5:56 pm.
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 1,873
Reputation: twomers has a spectacular aura about twomers has a spectacular aura about twomers has a spectacular aura about 
Solved Threads: 56
twomers's Avatar
twomers twomers is offline Offline
Posting Virtuoso

Re: Beginner: Variable loses last letter upon return from function

 
0
  #2
Aug 8th, 2009
Curious. You should use std::strings really...
  1. std::string strItoA(int number) {
  2. std::ostringstream sin;
  3. sin << number;
  4. return sin.str();
  5. }
Though Narue may tell you to generalise (which is a good idea, even though she spells it wrong ) which is where templates become your friend.
Last edited by twomers; Aug 8th, 2009 at 6:08 pm.
I blag!?
"Mr Kitty, you have to live in the attic now. Here, write a diary."
I am the Walrus!
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 1,928
Reputation: firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all 
Solved Threads: 254
firstPerson's Avatar
firstPerson firstPerson is offline Offline
Posting Virtuoso

Re: Beginner: Variable loses last letter upon return from function

 
0
  #3
Aug 8th, 2009
.
Last edited by firstPerson; Aug 8th, 2009 at 6:16 pm.
Reply With Quote Quick reply to this message  
Join Date: Aug 2009
Posts: 7
Reputation: NeoFryBoy is an unknown quantity at this point 
Solved Threads: 0
NeoFryBoy NeoFryBoy is offline Offline
Newbie Poster

Re: Beginner: Variable loses last letter upon return from function

 
0
  #4
Aug 8th, 2009
Originally Posted by twomers View Post
Curious. You should use std::strings really...
  1. std::string strItoA(int number) {
  2. std::ostringstream sin;
  3. sin << number;
  4. return sin.str();
  5. }
Though Narue may tell you to generalise (which is a good idea, even though she spells it wrong ) which is where templates become your friend.

That doesn't help at all. But thanks for the attempt.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 1,928
Reputation: firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all firstPerson is a name known to all 
Solved Threads: 254
firstPerson's Avatar
firstPerson firstPerson is offline Offline
Posting Virtuoso

Re: Beginner: Variable loses last letter upon return from function

 
0
  #5
Aug 8th, 2009
Last edited by firstPerson; Aug 8th, 2009 at 6:46 pm.
Reply With Quote Quick reply to this message  
Join Date: Jan 2009
Posts: 430
Reputation: JasonHippy is just really nice JasonHippy is just really nice JasonHippy is just really nice JasonHippy is just really nice JasonHippy is just really nice 
Solved Threads: 77
JasonHippy's Avatar
JasonHippy JasonHippy is offline Offline
Posting Pro in Training

Re: Beginner: Variable loses last letter upon return from function

 
0
  #6
Aug 8th, 2009
Originally Posted by NeoFryBoy View Post
Quick background: I'm working on Project Euler and made a palindrome checker. I needed to convert integers to strings. itoa() kept giving random values (9 gave 9 or 90, etc...), so I decided to make my own, and ran into a problem. I have fixed it, but could somebody explain what caused the problem and why the fix works?

Broken Code: The below code creates a stringstream inputs the number then puts that into a string and then into a char. The problem is it would chop the last number off when returning the char. (The buffer holds the 99800 value but the receiving variable numaschar = strItoA(num); becomes 9980.)

  1. char* strItoA(int number)
  2. {
  3. std::ostringstream sin;
  4. sin << number;
  5. std::string val = sin.str();
  6.  
  7. size_t length;
  8. char buffer[val.size()+1]; //add one for the zero terminator
  9. length=val.copy(buffer,val.length(),0); //do the transfer and grab the last position
  10. buffer[length]='\0'; //zero terminate!!
  11. return buffer;
  12. }

The Fix:
  1. char* buffer; //moved outside of function and given reference
  2.  
  3. char* strItoA(int number)
  4. {
  5. //Same...
  6.  
  7. buffer = new char [val.size()+1]; //added to keep buffer dynamic
  8. //char buffer[val.size()+1]; //removed
  9. //Same...
  10. }

Thanks.
Looking briefly at the first block of code, I think it's because the char buffer is declared inside your function and only has scope inside your function. So as soon as your function returns, the object referenced by the returned value has been invalidated as it is out of scope. In which case you're lucky to have anything sensible at all in the return value. That or perhaps you were overwriting the last character in the char array at line 10, where you're adding the null terminator.
I think the calculation of length in line 9 is incorrect as it holds the number of characters in the array (excluding the null terminator) so changing line 10 to:
  1. buffer[val.size()]='\0';
May fix the problem...
You've already stated in your code that the buffer should be the size of val.size()+1. after copying the contents of val into the buffer, the string in the buffer will be the same size as the string in val. So the item in the buffer at the array position buffer[val.size()] must therefore be the null terminator.

Remember: You've reserved val.size()+1 spaces for buffer and in c++, arrays start at position 0. Therefore the array position at the index val.size() must be the position reserved for the null terminator!

However in your first block of code, all of that stuff copying into the char buffer strikes me as unnecessary, plus there is the scope problem. I think all you needed to do was this:
  1. char* strItoA(int number)
  2. {
  3. std::ostringstream sin;
  4. sin << number;
  5.  
  6. return new std::string(sin.str()).c_str();
  7. // The above line is equivalent to:
  8. // std::string val = new std::string(sin.str());
  9. // return val.c_str();
  10. // c_str() returns a c-style string (char*) from a std::string
  11. // you can also get a char* from an ostringstream
  12. // e.g. sin.str().c_str()
  13. }

Hope this is of some help.
Cheers for now,
Jas.
Last edited by JasonHippy; Aug 8th, 2009 at 6:49 pm.
Will be posting sparsely, still lots of band related stuff to do:
http://www.myspace.com/kinasis
Reply With Quote Quick reply to this message  
Join Date: Aug 2009
Posts: 7
Reputation: NeoFryBoy is an unknown quantity at this point 
Solved Threads: 0
NeoFryBoy NeoFryBoy is offline Offline
Newbie Poster

Re: Beginner: Variable loses last letter upon return from function

 
0
  #7
Aug 8th, 2009
Hmmm I had thought return would dump the value into a new variable before deleting the old one.

I had extended the buffer size at one point so I'm sure I wasn't overwriting.

Well, thanks for suggesting the unique usage of c_str(). I had seen it used before, but they used strcpy() along with it and I was told not to use that function.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:




Views: 457 | Replies: 6
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2010 DaniWeb® LLC