Returning a pointer from a function

May 6, 2011 at 11:09pm
Hello all,

I have a basic question in C++.

In the code below, I am creating a local variable in a function and returning its address.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

#include <iostream>

using namespace std;

int* foo();

int main(int argc, char* argv[])
{
	
	int *ptr = foo();    //line 1
	int val = *foo();    //line 2

	int *p = new int;  //if these two lines are removed both give result '5'
	*p = 9;

	cout<<*ptr;         //first cout
	cout<<"\n"<<val;    //second cout
	
	
	return 0;
}


int* foo()
{
	
	int a = 5;
	int *c = &a;
	return c;
}


My understanding is, the variable is local to the the function. So returning its address does not sound like a meaningful thing to do. However, line 2 (commented), seems to gives the value '5'. line 1 gives a junk value (although it can give the correct value if I get lucky.For example, if I remove the line int *p = new int; below it).

Could somebody explain to me from a memory stand point, what the differences between
1
2
int *ptr = foo();   
int val = *foo();

are and what does it mean to return an address of a local variable created in a function?

Also, if the first one is wrong, what confused me is the value statements in Gary Bradsky's Learning opencv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IplImage* doPyrDown(
  IplImage* in,
  int filter = IPL_GAUSSIAN_5x5
) {

    // Best to make sure input image is divisible by two.
    //
    assert( in->width%2 == 0 && in->height%2 == 0 );

    IplImage* out = cvCreateImage( 
        cvSize( in->width/2, in->height/2 ),
        in->depth,
        in->nChannels
    );
    cvPyrDown( in, out );
    return( out );
};


This looks similar to line 1, (which gives junk value)

Thanks!
May 6, 2011 at 11:22pm
It looks like foo() is returning an invalid pointer; that is, it returns an address that points to memory that is no longer being used.
In line 1 it seems obvious why it later gets dereferenced into garbage data; however in line 2 the address is getting dereferenced very shortly (the very next step) after the function returns which means memory will most likely still contain the correct information, then that value (5) is copied into the variable "val". This is not good practice though, and there is no guarantee that "val" will not contain garbage data as well.
May 7, 2011 at 3:17pm
Thanks Mathhead200 for the reply.

I still don't understand how this works in OpenCV.
I saw code similar to line 2 used here - http://www.functionx.com/cpp/examples/returnpointer.htm, so it confused me more.
What I understood is, if you can allocate non-local memory within a function , for example using malloc or new, you are guaranteed that you can access it outside the function. So it seems the opencv function cvCreateImage invoked in the function allocates non-local memory.
So the correct version would be
1
2
3
4
5
6
7
int* foo()
{
	
	int *a = new int;
        *a = 5;
	return a;
}

Correct me if I am wrong.
May 9, 2011 at 2:48am
Here you are allocating the memory with new so it will not be deallocated until you call delete on the pointer (memory address.) This function will always return a pointer that points to 5. int *a does not point to invalid memory after it returns from the function like before. However a's value (memory address) is copied as the function's return value so if you don't copy it somewhere so it can later be deleted you will have a memory leak. Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

int* foo() {
	int *a = new int; //create an int, store a pointer to it in a
	*a = 5; //store 5 in the memory pointed to by a
	return a; //return the address of the int (it's stored in a)
}

int main() {
	...
	while( ... ) {
		std::cout << *foo() << '\n'; //print's 5
			// Whoops! The address returned by the function gets lost, and there is now no way to delete it.
	}
	...
	return 0;
}
May 9, 2011 at 8:59pm
Thanks!
Topic archived. No new replies allowed.