[comp.lang.c] ## question on memory allocation for char strings ##

siping@cathedral.cerc.wvu.wvnet.edu (Siping Liu) (06/29/90)

look at this example:
/**************************/
main()
{
  f1(f2());
}

f1(parm1)
char parm1[];
{
  printf("%s", parm1);
}

char *f2()
{
  char abc[100];

  strcpy(abc, "12345");

  return(abc);
}
/*******************************/

The question is: can I get the correct print out in function "f2"
as I have set in function "f1" ?? After the program returned from "f2",
memory space for "abc" was freed and may be used when calling "f1". So
even I get a correct print out, I still question if it's correct.

I have been told a lot of times that "strcpy" is always safe, but
I replace "f1" above by "strcpy", then how can I guarantee that it is safe?

Thanks in advance.

siping@cerc.wvu.wvnet.edu

writer@me.utoronto.ca (Tim Writer) (06/29/90)

In article <601@babcock.cerc.wvu.wvnet.edu> siping@cathedral.cerc.wvu.wvnet.edu (Siping Liu) writes:

>main()
>{
>  f1(f2());
>}

>f1(parm1)
>char parm1[];
>{
>  printf("%s", parm1);
>}

>char *f2()
>{
>  char abc[100];

>  strcpy(abc, "12345");

>  return(abc);
>}

>The question is: can I get the correct print out in function "f2"
>as I have set in function "f1" ?? After the program returned from "f2",
>memory space for "abc" was freed and may be used when calling "f1". So
>even I get a correct print out, I still question if it's correct.

If you declare abc to be static in f2(), it will be permanent.  That is, it
will not be freed on return from f2().  This will guarantee that printf()
in f1() prints the correct string.

Tim

roger@zuken.co.jp (Roger Meunier) (06/29/90)

In article <601@babcock.cerc.wvu.wvnet.edu> siping@cathedral.cerc.wvu.wvnet.edu (Siping Liu) writes:

 >char *f2()
 >{
 >  char abc[100];
 >
 >  strcpy(abc, "12345");
 >
 >  return(abc);
 >}

If you want to use the return value from f2() safely, make abc storage
class static, not automatic.  No variable in f2()'s scope is safe
outside of f2() otherwise.

--
Roger Meunier @ Zuken, Inc.  Yokohama, Japan	(roger@zuken.co.jp)

mcdaniel@amara.uucp (Tim McDaniel) (06/29/90)

"Ayatollah C" here!

"abc" is an "auto" variable in "f2".  When f2 returns, the space can
be reclaimed.  Thus, the return value from "f2", a pointer to the
space, then points nowhere.  FlexeLint warns you of this problem.

(Well, the space MIGHT actually remain in existance, due to quirks of
the implementation.  However, you can't depend on it.)

> look at this example:

Actually, I'd prefer not to.  I know it's only an example, but could
you at least post an example that compiles, much less has decent
style?  There's too much sloppy C coding in the world as it is to be
encouraging more.

Two of my personal style rules:
* Declare before use, even if C seems to let me get away with it.
  f1 was not a problem, but f2 was.
* Don't lie to the compiler.
  If a function doesn't return a value, I define it "void".
  If a function is taking a pointer, I say so.
  If I'm using old-style declarations, I don't define formal arguments
  as "[unsigned] char", "[unsigned] short", or "float".  C won't pass
  those types; they fall under the "default promotions."

I ran the program in the base note thru FlexeLint, the fine ANSI C
compliant lint from Gimpel Software (US phone number 1 215 584 4261).

It found
* 1 syntax error
   - f2 was implicitly declared to return "int" at its first use,
     but was later defined to return "char *".  (Fix: declare
     it before its first use.)
* 2 major bugs
   - printf was never declared (Fix: #include <stdio.h>)
   - f2 returns the address of an auto variable (abc).  (Fix in this
     case: declare "abc" to be "static".)
* 1 minor bug
   - main returns a random value to the environment.  (Fix:
     "return 0;" or "exit(0);" at the end of "main".)
* 3 instances of bad style
   - f1 was not declared before its first use.  (Fix: do so.)
   - f1 was implicitly defined to return "int", but never returned
     a value.  (Fix: most compilers allow "void" return type.)
   - strcpy was never declared.  (Fix: #include <string.h> or
     <strings.h>, as appropriate to your system.)
* a total lack of function prototypes.  (Can't fix right now on most
  compilers.  I'd recommend gcc, but it's a little fragile and
  bug-ridden.)

Also, I would not write
> char parm1[];
in f1.  You can't pass arrays by value in C; if you seem to, it's
actually passing a pointer to the first element.  Thus, the compiler
internally rewrites the declaration as
> char *parm1;

(P. S.  My only connection, financial or otherwise, with Gimpel
Software is as a VERY satisfied customer.  The one obscure bug I found
was fixed in a day or two.)
--
"I'm not a nerd -- I'm 'socially challenged'."

Tim McDaniel
Internet: mcdaniel@adi.com             UUCP: {uunet,sharkey}!puffer!mcdaniel