[newbie] return local variable (or pointer to object) from function

M

Mark

Hi

#include <stdio.h>int foo1(void){ int p; p = 99; return p;}char
*foo2(void){ char buffer[] = "test_123"; return buffer;}int
*foo3(void){ int t[3] = {1,2,3}; return t;}int main(void){ int *p;
char *s; printf("foo1: %d\n", foo1()); printf("foo2: %s\n", foo2());
printf("foo3: %d, %d, %d\n", p[0], p[1], p[2]); return 0;}Compiling all
three cases with "gcc -ansi -pedantic -W -Wall" and the compiler issues
warning messages for foo2() and foo3() and thus foo2 and foo3 prints out
garbage:

warning: function returns address of local variableI thought it is not
allowed to return a local variable, but foo1() works fine and it seems there
is a huge difference between returning pointer to a local object and the
object itself.

Could anybody shed some light on this issue? Thanks in advance!
 
M

Mickey Mouse

Hi


#include <stdio.h>
int foo1(void)
{
int p;

p = 99;
return p;
}

char *foo2(void)
{
char buffer[] = "test_123";
return buffer;
}

int *foo3(void)
{
int t[3] = {1,2,3};
return t;
}

int main(void)
{
int *p;
char *s;
printf("foo1: %d\n", foo1());
printf("foo2: %s\n", foo2());
printf("foo3: %d, %d, %d\n", p[0], p[1], p[2]);
return 0;
}

Compiling all
three cases with "gcc -ansi -pedantic -W -Wall" and the compiler issues
warning messages for foo2() and foo3() and thus foo2 and foo3 prints out
garbage:

warning: function returns address of local variableI thought it is not
allowed to return a local variable, but foo1() works fine and it seems there
is a huge difference between returning pointer to a local object and the
object itself.

Could anybody shed some light on this issue? Thanks in advance!

foo2 and foo3 both have the same problem. A variable declaied in a
function only has scope (only valid) in side the function.

int *p is used un initilized but with the expectation that it will
print the return values for foo3.

Try the functions below.



char *foo2(void)
{
char* buffer = malloc(strlen("test_123") + 1);

if ( buffer != NULL)
strcpy(buffer, "test_123");
return buffer;
}

int *foo3(void)
{
int *t = malloc(sizeof(int) * 3);

if (t != NULL)
{
t[0] =1;
t[1] = 2;
t[2] = 3;
}
return t;
}


int main(void)
{
int *p = foo3();
char *s = foo2();

printf("foo1: %d\n", foo1());

if (s != NULL)
{
printf("foo2: %s\n", s);
free(s);
}
else
printf("foo2: returned NULL\n");

if (p != NULL)
{
printf("foo3: %d, %d, %d\n", p[0], p[1], p[2]);
free(p);
}
else
printf("foo3: returned NULL\n");
return 0;
}
 
B

Ben Bacarisse

Mark said:
warning: function returns address of local variableI thought it is not
allowed to return a local variable, but foo1() works fine and it seems
there is a huge difference between returning pointer to a local object
and the object itself.

Yes there is. You can't return the object itself. Al you can do (in C)
is return values. Objects are pieces of storage that contain values and
locally declared objects disappear when the function containing the
declaration returns.

From that it should be clear that returning a pointer to a local object
is going to cause trouble -- the object pointed to is about to
disappear. Your foo1 is OK because the line:

return p;

returns the value contained in the object p.
Could anybody shed some light on this issue? Thanks in advance!

You might find the FAQ useful: http://c-faq.com/
 
A

Angus

Yes there is.  You can't return the object itself.  Al you can do (in C)
is return values.  Objects are pieces of storage that contain values and
locally declared objects disappear when the function containing the
declaration returns.

From that it should be clear that returning a pointer to a local object
is going to cause trouble -- the object pointed to is about to
disappear.  Your foo1 is OK because the line:

  return p;

returns the value contained in the object p.


You might find the FAQ useful:http://c-faq.com/

On my compiler the output is
foo1: 99
foo2: test_123
foo3: 1, 2, 3

I guess on other compilers this will not always work?
 
B

Ben Bacarisse

Angus said:
From that it should be clear that returning a pointer to a local object
is going to cause trouble -- the object pointed to is about to
disappear.

Best not to quote sig blocks (even short ones).
On my compiler the output is
foo1: 99
foo2: test_123
foo3: 1, 2, 3

I guess on other compilers this will not always work?

In some sense it may not even work on that compiler in that it probably
works by accident. Small changes to the program could produce all sorts
of odd effects. Even altering the compiler's options could change the
behaviour.
 
M

Mickey Mouse

Another real possibility is that it works as shown on 99% of the runs, but
prints gibberish on the other 1%.

Thats OK I can read and write gibberish. After enough beers I can
fluently speak it as well :)
 
A

Angus

From that it should be clear that returning a pointer to a local object
is going to cause trouble -- the object pointed to is about to
disappear.

Best not to quote sig blocks (even short ones).
On my compiler the output is
foo1: 99
foo2: test_123
foo3: 1, 2, 3
I guess on other compilers this will not always work?
In some sense it may not even work on that compiler in that it probably
works by accident.  Small changes to the program could produce all sorts
of odd effects.  Even altering the compiler's options could change the
behaviour.

Another real possibility is that it works as shown on 99% of the runs, but
prints gibberish on the other 1%.  This can happen on real computers that
use the same stack to hold both automatics and interrupt contexts.

This is Yet Another reason to avoid undefined behavior; just because your
program works once does not mean that it'll work the next time; even if
you'll rerun the exact same program...

I believe it IS ok to return a static variable.
 
K

Keith Thompson

Angus said:
I believe it IS ok to return a static variable.

It's not *possible* to return a static variables. As someone already
explained upthread, functions do not return variables; they return
values.

A function may return the *value* of a variable, and that's perfectly ok
(as long as that value doesn't contain a pointer to a local object). Or
it may return the *address* of a variable, which is ok if and only if
the variable's lifetime doesn't end when the current invocation of the
function does.

So what you probably *meant* to say is correct: it's ok for a function
to return the address of a static variable, because such a variable's
lifetime is the entire execution of the program. (But making a variable
static changes its behavior, which may or may not be what you want.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top