Is it legal to return a local variable from function.

R

Richard Tobin

hari said:
Is it legal to return a local variable from function.

You'll have to be more specific. You can't return variables, only
values. You can certainly return the value of a local variable. You
can't safely return a pointer to a local variable, because it won't
exist after the return.

-- Richard
 
S

santosh

hari said:
Hi all,
Is it legal to return a local variable from function.

Yes. Returning a pointer to it however is dangerous unless the said
local is static.
 
A

arunmib

Yes. Returning a pointer to it however is dangerous unless the said
local is static.

Well, I have a doubt. If I allocate memory for a local pointer and
return the address of the pointer to the calling function. Now will
this be dangerous. For eg:

int main()
{
char *test(int i);
char *tmp = NULL;
int i = 10;
tmp = test(i);
printf("%s\n", tmp);
free(tmp);
return 0;
}

char *test(int i)
{
char *str = (char*)malloc(20);
sprintf(str, "i value is: %d", i);
return str;
}
 
J

Joachim Schmitz

arunmib said:
Well, I have a doubt. If I allocate memory for a local pointer and
return the address of the pointer to the calling function. Now will
this be dangerous. For eg:

int main()
{
char *test(int i);
char *tmp = NULL;
int i = 10;
tmp = test(i);
printf("%s\n", tmp);
free(tmp);
return 0;
}

char *test(int i)
{
char *str = (char*)malloc(20);
sprintf(str, "i value is: %d", i);
return str;
}
In this case it is save to return *str. It is unsafe though to a) cast the
result of the malloc, b) not check whether it succeededs and then writing to
/ read from the unchecked result, c) pass an int to that function that
requires more than 7 characters in decimal

Bye, Jojo
 
R

Richard Heathfield

arunmib said:

Well, I have a doubt. If I allocate memory for a local pointer and
return the address of the pointer to the calling function. Now will
this be dangerous. For eg:

int main()
{
char *test(int i);
char *tmp = NULL;
int i = 10;
tmp = test(i);
printf("%s\n", tmp);
free(tmp);
return 0;
}

char *test(int i)
{
char *str = (char*)malloc(20);
sprintf(str, "i value is: %d", i);
return str;
}

First, the bugs. You forgot to #include <stdlib.h> and <stdio.h> - your
compiler would certainly have warned you that something was amiss, if only
you hadn't silenced it with a useless cast. You assume without
justification that the memory allocation request succeeded.

Okay, now to your question.

You haven't allocated any memory "for a local pointer". You've allocated
some memory, full stop. When you do so, you are given a value, which you
can use for referring to that memory. It's a pointer value (which points
to the beginning of the memory you've allocated). You have stored that
pointer value into a pointer object, which is a very right and proper
thing to do.

You have then returned that value, the value of the pointer object, to the
calling function. You have *not* returned the str object, merely its
value, which - if you will recall - points to the beginning of the memory
you allocated. That's absolutely fine, because that memory you allocated
via malloc (if indeed it succeeded at all) will continue to exist until
you explicitly release it by passing that pointer value to free().
 
S

santosh

arunmib said:
Well, I have a doubt. If I allocate memory for a local pointer and
return the address of the pointer to the calling function. Now will
this be dangerous. For eg:

int main()
{
char *test(int i);

Generally it's better to place declarations outside functions.
Specifically, it is needed (not strictly speaking, but calling a
function without a prototype is bad coding for most purposes), if a
function other than main() wants to invoke test().
char *tmp = NULL;
int i = 10;
tmp = test(i);
printf("%s\n", tmp);
free(tmp);
return 0;
}

char *test(int i)
{
char *str = (char*)malloc(20);

The cast is not recommended practise in C. It can prevent the compiler
from issuing a diagnostic if a prototype for malloc() is not in scope,
as is the case here. That in turn can cause subtle problems, since the
compiler incorrectly assumes that malloc() returns an int, while,
actually, it returns a void *.

Include stdio.h and stdlib.h before the code for this program.
sprintf(str, "i value is: %d", i);

If the value held in 'i' requires more than seven characters to
represent in decimal this sprintf() call will overwrite memory. For
such cases use snprintf().
return str;

This is fine since what is being returned is the _value_ in 'str',
not 'str' itself, which ceases to exist after this return. The value
however is copied and assigned to 'tmp' in main().
 
C

CBFalconer

arunmib said:
.... snip ...

Well, I have a doubt. If I allocate memory for a local pointer and
return the address of the pointer to the calling function. Now will
this be dangerous. For eg:

int main() {
char *test(int i);
char *tmp = NULL;
int i = 10;
tmp = test(i);
printf("%s\n", tmp);
free(tmp);
return 0;
}

char *test(int i) {
char *str = (char*)malloc(20);
sprintf(str, "i value is: %d", i);
return str;
}

You didn't return the address of the pointer, you returned the
pointer. All is well (except for the foolish cast on the return
value of malloc, and the lack of #includes, and the missing void in
the main parameter list).
 
A

arunmib

Thanks for all your replies.

The code I gave was only to make the understanding of my question's
concept and thats it, nothing more nothing less. No intention for
compiling or doing any other thing with the code. yeah, i know you
need to do #includes and about casting of 'malloc' return, use
snprintf instead of sprintf etc..
 
R

Richard Heathfield

arunmib said:
Thanks for all your replies.

The code I gave was only to make the understanding of my question's
concept and thats it, nothing more nothing less. No intention for
compiling or doing any other thing with the code. yeah, i know you
need to do #includes and about casting of 'malloc' return,

About *NOT* casting of malloc return value. There is no benefit to casting
it, and a slight cost in doing so.
use snprintf instead of sprintf etc..

Why? If I tried that, my compiler would laugh at me, and my linker would
have hysterics.
 
S

santosh

arunmib said:
Thanks for all your replies.

The code I gave was only to make the understanding of my question's
concept and thats it, nothing more nothing less. No intention for
compiling or doing any other thing with the code.

Personally I always compile code, even trivial, illustrative programs. A
good compiler, (with the appropriate switches), and a lint program can
turn up a surprising amount of issues with even small amounts of code.
 
D

David Thompson

In this case it is save to return *str.

Corrected to (the value of) str. Yes.
It is unsafe though to a) cast the result of the malloc,

Not strictly unsafe, but unhelpful because it can mask the error of
not #include'ing the required header, and at best is clutter.
b) not check whether it succeededs and then writing to
/ read from the unchecked result,
Yes.

c) pass an int to that function that
requires more than 7 characters in decimal
7? How's that? More than 19, yes, or negative more than 18. That would
require int >= 61 bits, which is permitted by the Standard but rare.
Although there is one person here who would make it more common. <G>

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top