943,589 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 5272
  • C++ RSS
Nov 25th, 2008
0

Problem with Returning Pointer to local variable

Expand Post »
Hello, everybody.
first, look at the following code:

C++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. 1 using std::cout;
  4. 2 using std::endl;
  5. 3 using std::cin;
  6. 4
  7. 5 double* treble(double);
  8. 6
  9. 7 int main(void)
  10. 8 {
  11. 9 double num = 5.0;
  12. 10 double* ptr = 0;
  13. 11 ptr = treble(num);
  14. 12 cout << endl
  15. 13 << "Three times num = " << 3.0*num << endl;
  16. 14 cout << "Result = " << *ptr;
  17. 15 cout << endl;
  18. 16 return 0;
  19. 17 }
  20. 18
  21. 19 double* treble(double data)
  22. 20 {
  23. 21 double result = 0.0;
  24. 22 result = 3.0*data;
  25. 23 return &result;
  26. 24 }

the output from this program is something like:

Three times num = 15
Result = 4.10416e-230

I know that the returned pointer of the function treble is point to local variable so when I returned, the value which inside that address has been lost.
there is no problem till here,
but let us to change the lines 13,14 to become:

C++ Syntax (Toggle Plain Text)
  1. 13 << "Three times num = " << 3.0*num << endl
  2. 14 << "Result = " << *ptr;
the output will become:

Three times num = 15
Result = 15

why?
Similar Threads
Reputation Points: 10
Solved Threads: 1
Newbie Poster
ALAZHARY is offline Offline
14 posts
since Jul 2006
Nov 25th, 2008
0

Re: Problem with Returning Pointer to local variable

The behaviour when dereferencing an invalid pointer is undefined. So I can only speculate on the underlying reason: it probably has to do with how and where stack variables are allocated, e.g. sequential function calls within a given scope might allocate stack variables from the same starting place, so stuff that's stack-allocated in the first call to cout << is likely to overwrite anything that was stack allocated on the prior call to treble. When it's done all in one call to cout <<, the value is fetched back before calling any other function, and thus before it's likely for it to have been overwritten, and it appears to work ok.

You can occasionaly predict how the thing is going to behave, e.g., I was pretty sure that this would happen:
C++ Syntax (Toggle Plain Text)
  1. double num = 5.0;
  2. double* ptr = 0;
  3. ptr = treble(num);
  4. treble( 2.0 );
  5. cout << endl << "Three times num = " << 3.0*num << endl << "Result = " << *ptr;

Outputs:
Three times num = 15
Result = 6

On my machine, but I wouldn't bet on it being the same as yours, and I'd never rely on it working like that on mine.

A clearer example:
C++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2.  
  3. int fn_a ( void )
  4. {
  5. int a = 0;
  6. std::cerr << &a << std::endl;
  7. }
  8.  
  9. int fn_b ( void )
  10. {
  11. int b = 0;
  12. std::cerr << &b << std::endl;
  13. }
  14.  
  15. int main ( void )
  16. {
  17. fn_a ( );
  18. fn_b ( );
  19.  
  20. return EXIT_SUCCESS;
  21. }

Outputs:
0xbff36764
0xbff36764

E.g. both function calls allocated a temporary variable in the same place, on my machine, today. (emphasis: "don't ever rely on this")

The important question, why are you doing this anyway?
C++ Syntax (Toggle Plain Text)
  1. double treble(double data)
  2. {
  3. double result = 0.0;
  4. result = 3.0*data;
  5. return result;
  6. }
Is much more normal and safe.
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Nov 25th, 2008
0

Re: Problem with Returning Pointer to local variable

result is a local variable, which is destroyed when the functions ends. So a garbage value is destroyed. The best solution is to do what is said by the poster above.

If you need to work with pointers you can do this:

C++ Syntax (Toggle Plain Text)
  1. double* treble(double data)
  2. {
  3. double result = 0.0;
  4. result = 3.0*data;
  5. return new result;
  6. }

now result isn't destroyed and a pointer to it is returned. However, this memory must be freed manually.

delete ptr;
Reputation Points: 13
Solved Threads: 8
Junior Poster in Training
minas1 is offline Offline
81 posts
since Nov 2008
Nov 25th, 2008
0

Re: Problem with Returning Pointer to local variable

Click to Expand / Collapse  Quote originally posted by minas1 ...
result is a local variable, which is destroyed when the functions ends. So a garbage value is destroyed. The best solution is to do what is said by the poster above.

If you need to work with pointers you can do this:

C++ Syntax (Toggle Plain Text)
  1. double* treble(double data)
  2. {
  3. double result = 0.0;
  4. result = 3.0*data;
  5. return new result;
  6. }

now result isn't destroyed and a pointer to it is returned. However, this memory must be freed manually.

delete ptr;
No errors means even number of errors
Incorrect example and wrong explanation (result always "destroyed": it's local automatic variable). Right "solution":
[code=c++]
double* treble(double data)
{
return new double(3.0*data);
}
Never, ever do that. It's totally senseless and a very dangerous programming style.
Reputation Points: 1234
Solved Threads: 347
Postaholic
ArkM is offline Offline
2,001 posts
since Jul 2008
Nov 26th, 2008
0

Re: Problem with Returning Pointer to local variable

thank you minas1, but I think you need to read carefully what is the problem?
Reputation Points: 10
Solved Threads: 1
Newbie Poster
ALAZHARY is offline Offline
14 posts
since Jul 2006
Nov 26th, 2008
0

Re: Problem with Returning Pointer to local variable

Click to Expand / Collapse  Quote originally posted by ALAZHARY ...
thank you minas1, but I think you need to read carefully what is the problem?
Actually: YOU need to read the replies carefully. MattEvans already told you what the problem is:

Click to Expand / Collapse  Quote originally posted by MattEvans ...
The behaviour when dereferencing an invalid pointer is undefined.
So just use the code posted by him and your problem will go away:
C++ Syntax (Toggle Plain Text)
  1. double treble(double data)
  2. {
  3. double result = 0.0;
  4. result = 3.0*data;
  5. return result;
  6. }
Moderator
Featured Poster
Reputation Points: 4142
Solved Threads: 394
Industrious Poster
Nick Evan is offline Offline
4,132 posts
since Oct 2006
Nov 26th, 2008
0

Re: Problem with Returning Pointer to local variable

I understood MattEvans well, but he speculate, and minas1 didn't understand my question
Reputation Points: 10
Solved Threads: 1
Newbie Poster
ALAZHARY is offline Offline
14 posts
since Jul 2006
Nov 26th, 2008
1

Re: Problem with Returning Pointer to local variable

That "the behaviour when dereferencing an invalid pointer is undefined" is fact.

Other than that, the best you'll get (in terms of an explanation for why you get this output) is speculation or some implementation-specific reason. On my implementation (GCC) reasonable evidence (see second code I posted) suggests that local variables in any function get allocated from the same starting address (assuming the calls come from the same level).

(EDIT: and that would be sufficient explanation for your output, providing std::ostream::operator<< allocates at least one local variable)

There's no requirement for "reclaimed" memory to be zeroed or otherwise restored (by reclaimed, I mean memory under deleted pointers or under auto variables that go out of scope). The most efficient implementation strategy is to just leave the contents of such memory untouched, hence, before reclaimed memory is overwritten, it will tend to contain its old value. (You shouldn't rely on this, either)
Last edited by MattEvans; Nov 26th, 2008 at 7:46 am.
Moderator
Featured Poster
Reputation Points: 522
Solved Threads: 64
Veteran Poster
MattEvans is offline Offline
1,091 posts
since Jul 2006
Nov 26th, 2008
0

Re: Problem with Returning Pointer to local variable

thank you very much MattEvans, your post was helpful.
Reputation Points: 10
Solved Threads: 1
Newbie Poster
ALAZHARY is offline Offline
14 posts
since Jul 2006

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: How to include .lib files
Next Thread in C++ Forum Timeline: Index of a character array





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC