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