Hello, everybody.
first, look at the following code:

#include <iostream>

1  using std::cout;
2  using std::endl;
3  using std::cin;
4
5  double* treble(double);
6
7  int main(void)
8  {
9   double num = 5.0;
10  double* ptr = 0;
11   ptr = treble(num);
12   cout << endl
13        << "Three times num = " << 3.0*num << endl;
14   cout << "Result = " << *ptr;
15   cout << endl;
16   return 0;
17 }
18
19  double* treble(double data)
20  {
21   double result = 0.0;
22   result = 3.0*data;
23   return &result;
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:

13        << "Three times num = " << 3.0*num << endl
14        << "Result = " << *ptr;

the output will become:

Three times num = 15
Result = 15

why?

Recommended Answers

All 8 Replies

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:

double num = 5.0;
double* ptr = 0;
ptr = treble(num);
treble( 2.0 );
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:

#include <iostream>

int fn_a ( void )
{
  int a = 0;
  std::cerr << &a << std::endl;
}

int fn_b ( void )
{
  int b = 0;
  std::cerr << &b << std::endl;
}

int main ( void )
{
  fn_a ( );
  fn_b ( );

  return EXIT_SUCCESS;
}

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?

double treble(double data)
 {
  double result = 0.0;
   result = 3.0*data;
  return result;
}

Is much more normal and safe.

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:

double* treble(double data)
{
	double result = 0.0;
	result = 3.0*data;
	return new result;
}

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

delete ptr;

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:

double* treble(double data)
{
	double result = 0.0;
	result = 3.0*data;
	return new result;
}

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":

double* treble(double data) { return new double(3.0*data); } Never, ever do that. It's totally senseless and a very dangerous programming style.[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.

thank you minas1, but I think you need to read carefully what is the problem?

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:

The behaviour when dereferencing an invalid pointer is undefined.

So just use the code posted by him and your problem will go away:

double treble(double data)
 {
  double result = 0.0;
   result = 3.0*data;
  return result;
}

I understood MattEvans well, but he speculate, and minas1 didn't understand my question

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)

commented: Excellent posts in this thread! +12

thank you very much MattEvans, your post was helpful.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.